JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> @since 2.7 */ Class<?> keyClass = findSerializationKeyType(a, keyType); if (keyClass != null) { if (keyType.hasRawClass(keyClass)) { keyType = keyType.withStaticTyping(); } else { Class<?> currRaw = keyType.getRawClass(); try { // 19-May-2016, tatu: As per [databind#1231], [databind#1178] may need to actually // specialize (narrow) type sometimes, even if more commonly opposite // is needed. if (keyClass.isAssignableFrom(currRaw)) { // common case keyType = tf.constructGeneralizedType(keyType, keyClass); } else if (currRaw.isAssignableFrom(keyClass)) { // specialization, ok as well keyType = tf.constructSpecializedType(keyType, keyClass); } else { throw new JsonMappingException(null, String.format("Can not refine serialization key type %s into %s; types not related", keyType, keyClass.getName())); } } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen key type of %s with concrete-type annotation (value %s), from '%s': %s", type, keyClass.getName(), a.getName(), iae.getMessage()), iae); } } type = ((MapLikeType) type).withKeyType(keyType); } } JavaType contentType = type.getContentType(); if (contentType != null) { // collection[like], map[like], array, reference // And then value types for all containers: Class<?> contentClass = findSerializationContentType(a, contentType); if (contentClass != null) { if (contentType.hasRawClass(contentClass)) { contentType = contentType.withStaticTyping(); } else { // 03-Apr-2016, tatu: As per [databind#1178], may need to actually // specialize (narrow) type sometimes, even if more commonly opposite // is needed. Class<?> currRaw = contentType.getRawClass(); try { if (contentClass.isAssignableFrom(currRaw)) { // common case contentType = tf.constructGeneralizedType(contentType, contentClass); } else if (currRaw.isAssignableFrom(contentClass)) { // specialization, ok as well contentType = tf.constructSpecializedType(contentType, contentClass); } else { throw new JsonMappingException(null, String.format("Can not refine serialization content type %s into %s;

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> * @since 2.7 */ public JavaType refineDeserializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> valueClass = findDeserializationType(a, type); if ((valueClass != null) && !type.hasRawClass(valueClass)) { try { type = tf.constructSpecializedType(type, valueClass); } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to narrow type %s with annotation (value %s), from '%s': %s", type, valueClass.getName(), a.getName(), iae.getMessage()), iae); } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); Class<?> keyClass = findDeserializationKeyType(a, keyType); if (keyClass != null) { try { keyType = tf.constructSpecializedType(keyType, keyClass); type = ((MapLikeType) type).withKeyType(keyType); } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to narrow key type of %s with concrete-type annotation (value %s), from '%s': %s", type, keyClass.getName(), a.getName(), iae.getMessage()), iae); } } } JavaType contentType = type.getContentType(); if (contentType != null) { // collection[like], map[like], array, reference // And then value types for all containers: Class<?> contentClass = findDeserializationContentType(a, contentType); if (contentClass != null) { try { contentType = tf.constructSpecializedType(contentType, contentClass); type = type.withContentType(contentType); } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to narrow value type of %s with concrete-type annotation (value %s), from '%s': %s", type,

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> to combine polymorphic types, Converters, but the least sucky way * is probably to use Converter and ignore polymorphic type. Alternative * would be to try to change `TypeDeserializer` to accept `Converter` to * invoke... but that is more intrusive, yet not guaranteeing success. */ // method called up to 2.7.3: // Object delegateValue = _delegateDeserializer.deserializeWithType(p, ctxt, typeDeserializer); // method called since 2.7.4 Object delegateValue = _delegateDeserializer.deserialize(p, ctxt); if (delegateValue == null) { return null; } return convertValue(delegateValue); } @SuppressWarnings("unchecked") @Override public T deserialize(JsonParser p, DeserializationContext ctxt, Object intoValue) throws IOException { if (_delegateType.getRawClass().isAssignableFrom(intoValue.getClass())){ return (T) _delegateDeserializer.deserialize(p, ctxt, intoValue); } return (T) _handleIncompatibleUpdateValue(p, ctxt, intoValue); } /** * Overridable handler method called when {@link #deserialize(JsonParser, DeserializationContext, Object)} * has been called with a value that is not compatible with delegate value. * Since no conversion are expected for such "updateValue" case, this is normally not * an operation that can be permitted, and the default behavior is to throw exception. * Sub-classes may choose to try alternative approach if they have more information on * exact usage and constraints. * * @since 2.6 */ protected Object _handleIncompatibleUpdateValue(JsonParser p, DeserializationContext ctxt, Object intoValue) throws IOException { throw new UnsupportedOperationException(String.format ("Can not update object of type %s (using deserializer for type %s)" +intoValue.getClass().getName(), _delegateType)); } /* /********************************************************** /* Overridable methods /********************************************************** */ /** * Method called to convert from "delegate value" (which was deserialized * from JSON using standard Jackson deserializer for delegate type) * into desired target type. *<P> * The default implementation uses configured {@link Converter} to do * conversion. * * @param delegateValue * * @return Result of conversion */ protected T convertValue(Object delegateValue) { return _converter.convert(delegateValue); } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> } break; case NON_ABSENT: // new with 2.6, to support Guava/JDK8 Optionals // always suppress nulls suppressNulls = true; // and for referential types, also "empty", which in their case means "absent" if (declaredType.isReferenceType()) { valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY; } break; case NON_EMPTY: // always suppress nulls suppressNulls = true; // but possibly also 'empty' values: valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY; break; case NON_NULL: suppressNulls = true; // fall through case ALWAYS: // default default: // we may still want to suppress empty collections, as per [JACKSON-254]: if (declaredType.isContainerType() && !_config.isEnabled(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)) { valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY; } break; } BeanPropertyWriter bpw = new BeanPropertyWriter(propDef, am, _beanDesc.getClassAnnotations(), declaredType, ser, typeSer, serializationType, suppressNulls, valueToSuppress); // How about custom null serializer? Object serDef = _annotationIntrospector.findNullSerializer(am); if (serDef != null) { bpw.assignNullSerializer(prov.serializerInstance(am, serDef)); } // And then, handling of unwrapping NameTransformer unwrapper = _annotationIntrospector.findUnwrappingNameTransformer(am); if (unwrapper != null) { bpw = bpw.unwrappingWriter(unwrapper); } return bpw; } /* /********************************************************** /* Helper methods; annotation access /********************************************************** */ /** * Method that will try to determine statically defined type of property * being serialized, based on annotations (for overrides), and alternatively * declared type (if static typing for serialization is enabled). * If neither can be used (no annotations, dynamic typing), returns null. */ protected JavaType findSerializationType(Annotated a, boolean useStaticTyping, JavaType declaredType) throws JsonMappingException { JavaType secondary = _annotationIntrospector.refineSerializationType(_config, a, declaredType); // 11-Oct-2015, tatu: As of 2.7, not 100% sure following checks are needed. But keeping // for now, just in case if (secondary != declaredType) { Class<?> serClass = secondary.getRaw

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Class(); // Must be a super type to be usable Class<?> rawDeclared = declaredType.getRawClass(); if (serClass.isAssignableFrom(rawDeclared)) { ; // fine as is } else { /* 18-Nov-2010, tatu: Related to fixing [JACKSON-416], an issue with such * check is that for deserialization more specific type makes sense; * and for serialization more generic. But alas JAXB uses but a single * annotation to do both... Hence, we must just discard type, as long as * types are related */ if (!rawDeclared.isAssignableFrom(serClass)) { throw new IllegalArgumentException("Illegal concrete-type annotation for method '"+a.getName()+"': class "+serClass.getName()+" not a super-type of (declared) class "+rawDeclared.getName()); } /* 03-Dec-2010, tatu: Actually, ugh, we may need to further relax this * and actually accept subtypes too for serialization. Bit dangerous in theory * but need to trust user here... */ } useStaticTyping = true; declaredType = secondary; } // If using static typing, declared type is known to be the type... JsonSerialize.Typing typing = _annotationIntrospector.findSerializationTyping(a); if ((typing != null) && (typing != JsonSerialize.Typing.DEFAULT_TYPING)) { useStaticTyping = (typing == JsonSerialize.Typing.STATIC); } if (useStaticTyping) { // 11-Oct-2015, tatu: Make sure JavaType also "knows" static-ness... return declaredType.withStaticTyping(); } return null; } /* /********************************************************** /* Helper methods for default value handling /********************************************************** */ protected Object getDefaultBean() { Object def = _defaultBean; if (def == null) { /* If we can fix access rights, we should; otherwise non-public * classes or default constructor will prevent instantiation */ def = _beanDesc.instantiateBean(_config.canOverrideAccessModifiers()); if (def == null) { // 06-Nov-2015, tatu: As per [databind#998], do not fail. /* Class<?> cls = _beanDesc.getClassInfo().getAnnotated(); throw new IllegalArgumentException("Class "+cls.getName()+" has no default constructor; can not instantiate default bean value to support 'properties=JsonSerialize.Inclusion.NON_DEFAULT' annotation"); */ // And use a marker def = NO_DEFAULT_MARKER; } _defaultBean

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> = def; } return (def == NO_DEFAULT_MARKER) ? null : _defaultBean; } /** * Accessor used to find out "default value" for given property, to use for * comparing values to serialize, to determine whether to exclude value from serialization with * inclusion type of {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_EMPTY}. * This method is called when we specifically want to know default value within context * of a POJO, when annotation is within containing class, and not for property or * defined as global baseline. *<p> * Note that returning of pseudo-type * * @since 2.7 */ protected Object getPropertyDefaultValue(String name, AnnotatedMember member, JavaType type) { Object defaultBean = getDefaultBean(); if (defaultBean == null) { return getDefaultValue(type); } try { return member.getValue(defaultBean); } catch (Exception e) { return _throwWrapped(e, name, defaultBean); } } /** * Accessor used to find out "default value" to use for comparing values to * serialize, to determine whether to exclude value from serialization with * inclusion type of {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_DEFAULT}. *<p> * Default logic is such that for primitives and wrapper types for primitives, expected * defaults (0 for `int` and `java.lang.Integer`) are returned; for Strings, empty String, * and for structured (Maps, Collections, arrays) and reference types, criteria * {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_DEFAULT} * is used. * * @since 2.7 */ protected Object getDefaultValue(JavaType type) { // 06-Nov-2015, tatu: Returning null is fine for Object types; but need special // handling for primitives since they are never passed as nulls. Class<?> cls = type.getRawClass(); Class<?> prim = ClassUtil.primitiveType(cls); if (prim != null) { return ClassUtil.defaultValue(prim); } if (type.isContainerType() || type.isReferenceType()) { return JsonInclude.Include.NON_EMPTY; } if (cls == String.class) { return ""; } return null; } /* /********************************************************** /* Helper methods for exception handling /********************************************************** */ protected Object _throwWrapped(Exception e, String propName, Object defaultBean) { Throwable t = e; while (t.getCause() != null)

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>015, tatu: As per [databind#749], we can not statically determine * between name() and toString(), need to construct `EnumValues` with names, * handle toString() case dynamically (for example) */ EnumValues v = EnumValues.constructFromName(config, (Class<Enum<?>>) enumClass); Boolean serializeAsIndex = _isShapeWrittenUsingIndex(enumClass, format, true); return new EnumSerializer(v, serializeAsIndex); } /** * To support some level of per-property configuration, we will need * to make things contextual. We are limited to "textual vs index" * choice here, however. */ @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { if (property != null) { JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated) property.getMember()); if (format != null) { Boolean serializeAsIndex = _isShapeWrittenUsingIndex(property.getType().getRawClass(), format, false); if (serializeAsIndex != _serializeAsIndex) { return new EnumSerializer(_values, serializeAsIndex); } } } return this; } /* /********************************************************** /* Extended API for Jackson databind core /********************************************************** */ public EnumValues getEnumValues() { return _values; } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public final void serialize(Enum<?> en, JsonGenerator gen, SerializerProvider serializers) throws IOException { // [JACKSON-684]: serialize as index? if (_serializeAsIndex(serializers)) { gen.writeNumber(en.ordinal()); return; } // [databind#749]: or via toString()? if (serializers.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) { gen.writeString(en.toString()); return; } gen.writeString(_values.serializedValueFor(en)); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { // [JACKSON-684]: serialize as index? if (_serializeAsIndex(provider)) { return createSchemaNode("integer", true); } ObjectNode objectNode = createSchemaNode("string", true); if (typeHint != null) { JavaType type = provider.constructType(typeHint); if (type.isEnumType()) { ArrayNode enumNode = objectNode.putArray("enum"); for (SerializableString value : _values.values()) { enumNode.add(

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> if (!JsonDeserializer.class.isAssignableFrom(deserClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>"); } HandlerInstantiator hi = _config.getHandlerInstantiator(); deser = (hi == null) ? null : hi.deserializerInstance(_config, ann, deserClass); if (deser == null) { deser = (JsonDeserializer<?>) ClassUtil.createInstance(deserClass, _config.canOverrideAccessModifiers()); } } // First: need to resolve if (deser instanceof ResolvableDeserializer) { ((ResolvableDeserializer) deser).resolve(this); } return (JsonDeserializer<Object>) deser; } @Override public final KeyDeserializer keyDeserializerInstance(Annotated ann, Object deserDef) throws JsonMappingException { if (deserDef == null) { return null; } KeyDeserializer deser; if (deserDef instanceof KeyDeserializer) { deser = (KeyDeserializer) deserDef; } else { if (!(deserDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type " +deserDef.getClass().getName() +"; expected type KeyDeserializer or Class<KeyDeserializer> instead"); } Class<?> deserClass = (Class<?>)deserDef; // there are some known "no class" markers to consider too: if (deserClass == KeyDeserializer.None.class || ClassUtil.isBogusClass(deserClass)) { return null; } if (!KeyDeserializer.class.isAssignableFrom(deserClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName() +"; expected Class<KeyDeserializer>"); } HandlerInstantiator hi = _config.getHandlerInstantiator(); deser = (hi == null) ? null : hi.keyDeserializerInstance(_config, ann, deserClass); if (deser == null) { deser = (KeyDeserializer) ClassUtil.createInstance(deserClass, _config.canOverrideAccessModifiers()); } } // First: need to resolve if (deser instanceof ResolvableDeserializer) { ((ResolvableDeserializer) deser).resolve(this); } return deser; } /* /********************************************************** /* Extended API /********************************************************** */ /** * Fluent factory method used for constructing a blueprint instance * with different factory */ public abstract DefaultDeserializationContext with(DeserializerFactory factory); /** * Method called to create actual usable per-deserialization * context instance. */ public abstract DefaultDeserializationContext createInstance( DeserializationConfig config, JsonParser

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> findPropertyInclusion(JsonInclude.Value defValue) { if (_annotationIntrospector != null) { JsonInclude.Value incl = _annotationIntrospector.findPropertyInclusion(_classInfo); if (incl != null) { return defValue.withOverrides(incl); } } return defValue; } /** * Method used to locate the method of introspected class that * implements {@link com.fasterxml.jackson.annotation.JsonAnyGetter}. * If no such method exists null is returned. * If more than one are found, an exception is thrown. */ @Override public AnnotatedMember findAnyGetter() throws IllegalArgumentException { AnnotatedMember anyGetter = (_propCollector == null) ? null : _propCollector.getAnyGetter(); if (anyGetter != null) { /* For now let's require a Map; in future can add support for other * types like perhaps Iterable<Map.Entry>? */ Class<?> type = anyGetter.getRawType(); if (!Map.class.isAssignableFrom(type)) { throw new IllegalArgumentException("Invalid 'any-getter' annotation on method "+anyGetter.getName()+"(): return type is not instance of java.util.Map"); } } return anyGetter; } @Override public Map<String,AnnotatedMember> findBackReferenceProperties() { HashMap<String,AnnotatedMember> result = null; // boolean hasIgnored = (_ignoredPropertyNames != null); for (BeanPropertyDefinition property : _properties()) { /* 23-Sep-2014, tatu: As per [Databind#426], we _should_ try to avoid * calling accessor, as it triggers exception from seeming conflict. * But the problem is that _ignoredPropertyNames here only contains * ones ignored on per-property annotations, but NOT class annotations... * so commented out part does not work, alas */ /* if (hasIgnored && _ignoredPropertyNames.contains(property.getName())) { continue; } */ AnnotatedMember am = property.getMutator(); if (am == null) { continue; } AnnotationIntrospector.ReferenceProperty refDef = _annotationIntrospector.findReferenceType(am); if (refDef != null && refDef.isBackReference()) { if (result == null) { result = new HashMap<String,AnnotatedMember>(); } String refName = refDef.getName(); if (result.put(refName, am) != null) { throw new IllegalArgumentException("Multiple back-reference properties with name '"+refName+"'"); } } } return result;

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> } /* /********************************************************** /* Introspection for deserialization, factories /********************************************************** */ @Override public List<AnnotatedMethod> getFactoryMethods() { // must filter out anything that clearly is not a factory method List<AnnotatedMethod> candidates = _classInfo.getStaticMethods(); if (candidates.isEmpty()) { return candidates; } ArrayList<AnnotatedMethod> result = new ArrayList<AnnotatedMethod>(); for (AnnotatedMethod am : candidates) { if (isFactoryMethod(am)) { result.add(am); } } return result; } @Override public Constructor<?> findSingleArgConstructor(Class<?>... argTypes) { for (AnnotatedConstructor ac : _classInfo.getConstructors()) { // This list is already filtered to only include accessible /* (note: for now this is a redundant check; but in future * that may change; thus leaving here for now) */ if (ac.getParameterCount() == 1) { Class<?> actArg = ac.getRawParameterType(0); for (Class<?> expArg : argTypes) { if (expArg == actArg) { return ac.getAnnotated(); } } } } return null; } @Override public Method findFactoryMethod(Class<?>... expArgTypes) { // So, of all single-arg static methods: for (AnnotatedMethod am : _classInfo.getStaticMethods()) { if (isFactoryMethod(am)) { // And must take one of expected arg types (or supertype) Class<?> actualArgType = am.getRawParameterType(0); for (Class<?> expArgType : expArgTypes) { // And one that matches what we would pass in if (actualArgType.isAssignableFrom(expArgType)) { return am.getAnnotated(); } } } } return null; } protected boolean isFactoryMethod(AnnotatedMethod am) { /* First: return type must be compatible with the introspected class * (i.e. allowed to be sub-class, although usually is the same * class) */ Class<?> rt = am.getRawReturnType(); if (!getBeanClass().isAssignableFrom(rt)) { return false; } /* Also: must be a recognized factory method, meaning: * (a) marked with @JsonCreator annotation, or * (b) "valueOf" (at this point, need not be public) */ if (_annotationIntrospector.hasCreatorAnnotation(am)) { return true; } final String name = am.getName(); if ("valueOf".equals(name)) { return true; }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> // [Issue#208] Also accept "fromString()", if takes String or CharSequence if ("fromString".equals(name)) { if (1 == am.getParameterCount()) { Class<?> cls = am.getRawParameterType(0); if (cls == String.class || CharSequence.class.isAssignableFrom(cls)) { return true; } } } return false; } /** * @deprecated Since 2.4, use <code>findCreatorParameterNames()</code> instead. */ @Deprecated public List<String> findCreatorPropertyNames() { List<PropertyName> params = findCreatorParameterNames(); if (params.isEmpty()) { return Collections.emptyList(); } List<String> result = new ArrayList<String>(params.size()); for (PropertyName name : params) { result.add(name.getSimpleName()); } return result; } /** * @deprecated Since 2.5, does not seem to be used at all. */ @Deprecated public List<PropertyName> findCreatorParameterNames() { for (int i = 0; i < 2; ++i) { List<? extends AnnotatedWithParams> l = (i == 0) ? getConstructors() : getFactoryMethods(); for (AnnotatedWithParams creator : l) { int argCount = creator.getParameterCount(); if (argCount < 1) continue; PropertyName name = _findCreatorPropertyName(creator.getParameter(0)); if (name == null || name.isEmpty()) { continue; } List<PropertyName> names = new ArrayList<PropertyName>(); names.add(name); for (int p = 1; p < argCount; ++p) { name = _findCreatorPropertyName(creator.getParameter(p)); names.add(name); } return names; } } return Collections.emptyList(); } protected PropertyName _findCreatorPropertyName(AnnotatedParameter param) { PropertyName name = _annotationIntrospector.findNameForDeserialization(param); if (name == null || name.isEmpty()) { String str = _annotationIntrospector.findImplicitPropertyName(param); if (str != null && !str.isEmpty()) { name = PropertyName.construct(str); } } return name; } /* /********************************************************** /* Introspection for deserialization, other /********************************************************** */ @Override public Class<?> findPOJOBuilder() { return (_annotationIntrospector == null) ? null : _annotationIntrospector.findPOJOBuilder(_classInfo); } @Override public JsonPOJOBuilder.Value findPO

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>JOBuilderConfig() { return (_annotationIntrospector == null) ? null : _annotationIntrospector.findPOJOBuilderConfig(_classInfo); } @Override public Converter<Object,Object> findDeserializationConverter() { if (_annotationIntrospector == null) { return null; } return _createConverter(_annotationIntrospector.findDeserializationConverter(_classInfo)); } @Override public String findClassDescription() { return (_annotationIntrospector == null) ? null : _annotationIntrospector.findClassDescription(_classInfo); } /* /********************************************************** /* Helper methods for field introspection /********************************************************** */ /** * @param ignoredProperties (optional) names of properties to ignore; * any fields that would be recognized as one of these properties * is ignored. * @param forSerialization If true, will collect serializable property * fields; if false, deserializable * * @return Ordered Map with logical property name as key, and * matching field as value. * * @deprecated Since 2.7.2, does not seem to be used? */ @Deprecated public LinkedHashMap<String,AnnotatedField> _findPropertyFields( Collection<String> ignoredProperties, boolean forSerialization) { LinkedHashMap<String,AnnotatedField> results = new LinkedHashMap<String,AnnotatedField>(); for (BeanPropertyDefinition property : _properties()) { AnnotatedField f = property.getField(); if (f != null) { String name = property.getName(); if (ignoredProperties != null) { if (ignoredProperties.contains(name)) { continue; } } results.put(name, f); } } return results; } /* /********************************************************** /* Helper methods, other /********************************************************** */ @SuppressWarnings("unchecked") public Converter<Object,Object> _createConverter(Object converterDef) { if (converterDef == null) { return null; } if (converterDef instanceof Converter<?,?>) { return (Converter<Object,Object>) converterDef; } if (!(converterDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type " +converterDef.getClass().getName()+"; expected type Converter or Class<Converter> instead"); } Class<?> converterClass = (Class<?>)converterDef; // there are some known "no class" markers to consider too: if (converterClass == Converter.None.class || ClassUtil.isBogusClass(converterClass)) { return null; } if (!Converter.class.isAssignableFrom(converterClass)) { throw new IllegalStateException("

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; /** * Deserializer for {@link EnumMap} values. * <p> * Note: casting within this class is all messed up -- just could not figure out a way * to properly deal with recursive definition of "EnumMap&lt;K extends Enum&lt;K>, V> */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class EnumMapDeserializer extends ContainerDeserializerBase<EnumMap<?,?>> implements ContextualDeserializer { private static final long serialVersionUID = 1; protected final JavaType _mapType; protected final Class<?> _enumClass; protected KeyDeserializer _keyDeserializer; protected JsonDeserializer<Object> _valueDeserializer; /** * If value instances have polymorphic type information, this * is the type deserializer that can handle it */ protected final TypeDeserializer _valueTypeDeserializer; /* /********************************************************** /* Life-cycle /********************************************************** */ public EnumMapDeserializer(JavaType mapType, KeyDeserializer keyDeserializer, JsonDeserializer<?> valueDeser, TypeDeserializer valueTypeDeser) { super(mapType); _mapType = mapType; _enumClass = mapType.getKeyType().getRawClass(); _keyDeserializer = keyDeserializer; _valueDeserializer = (JsonDeserializer<Object>) valueDeser; _valueTypeDeserializer = valueTypeDeser; } public EnumMapDeserializer withResolved(KeyDeserializer keyDeserializer, JsonDeserializer<?> valueDeserializer, TypeDeserializer valueTypeDeser) { if ((keyDeserializer == _keyDeserializer) && (valueDeserializer == _valueDeserializer) && (valueTypeDeser == _valueTypeDeserializer)) { return this; } return new EnumMapDeserializer(_mapType, keyDeserializer, valueDeserializer, _valueTypeDeserializer); } /** * Method called to finalize setup of this deserializer, * when it is known for which property deserializer is needed for. */ @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { // note: instead of finding key deserializer, with enums we actually // work with regular deserializers (less code duplication; but not // quite as clean as it ought to be) KeyDeserializer kd = _keyDeserializer; if (kd == null) { kd = ctxt.findKeyDeserializer(_mapType.getKeyType

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>(type, endBefore, result, addClassItself); return result; } /** * @since 2.7 */ public static List<Class<?>> findRawSuperTypes(Class<?> cls, Class<?> endBefore, boolean addClassItself) { if ((cls == null) || (cls == endBefore) || (cls == Object.class)) { return Collections.emptyList(); } List<Class<?>> result = new ArrayList<Class<?>>(8); _addRawSuperTypes(cls, endBefore, result, addClassItself); return result; } /** * Method for finding all super classes (but not super interfaces) of given class, * starting with the immediate super class and ending in the most distant one. * Class itself is included if <code>addClassItself</code> is true. * * @since 2.7 */ public static List<Class<?>> findSuperClasses(Class<?> cls, Class<?> endBefore, boolean addClassItself) { List<Class<?>> result = new LinkedList<Class<?>>(); if ((cls != null) && (cls != endBefore)) { if (addClassItself) { result.add(cls); } while ((cls = cls.getSuperclass()) != null) { if (cls == endBefore) { break; } result.add(cls); } } return result; } @Deprecated // since 2.7 public static List<Class<?>> findSuperTypes(Class<?> cls, Class<?> endBefore) { return findSuperTypes(cls, endBefore, new ArrayList<Class<?>>(8)); } @Deprecated // since 2.7 public static List<Class<?>> findSuperTypes(Class<?> cls, Class<?> endBefore, List<Class<?>> result) { _addRawSuperTypes(cls, endBefore, result, false); return result; } private static void _addSuperTypes(JavaType type, Class<?> endBefore, Collection<JavaType> result, boolean addClassItself) { if (type == null) { return; } final Class<?> cls = type.getRawClass(); if (cls == endBefore || cls == Object.class) { return; } if (addClassItself) { if (result.contains(type)) { // already added, no need to check supers return; } result.add(type); } for (JavaType intCls : type.getInterfaces()) { _addSuperTypes(intCls, endBefore, result, true); } _addSuperTypes(type.getSuperClass(), endBefore, result, true); }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> locals, anonymous, are not good: if (hasEnclosingMethod(type)) { return null; } if (!Modifier.isStatic(type.getModifiers())) { return getEnclosingClass(type); } } catch (SecurityException e) { } return null; } /** * Helper method used to weed out dynamic Proxy types; types that do * not expose concrete method API that we could use to figure out * automatic Bean (property) based serialization. */ public static boolean isProxyType(Class<?> type) { // As per [databind#57], should NOT disqualify JDK proxy: /* // Then: well-known proxy (etc) classes if (Proxy.isProxyClass(type)) { return true; } */ String name = type.getName(); // Hibernate uses proxies heavily as well: if (name.startsWith("net.sf.cglib.proxy.") || name.startsWith("org.hibernate.proxy.")) { return true; } // Not one of known proxies, nope: return false; } /** * Helper method that checks if given class is a concrete one; * that is, not an interface or abstract class. */ public static boolean isConcrete(Class<?> type) { int mod = type.getModifiers(); return (mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0; } public static boolean isConcrete(Member member) { int mod = member.getModifiers(); return (mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0; } public static boolean isCollectionMapOrArray(Class<?> type) { if (type.isArray()) return true; if (Collection.class.isAssignableFrom(type)) return true; if (Map.class.isAssignableFrom(type)) return true; return false; } /* /********************************************************** /* Type name handling methods /********************************************************** */ /** * Helper method used to construct appropriate description * when passed either type (Class) or an instance; in latter * case, class of instance is to be used. */ public static String getClassDescription(Object classOrInstance) { if (classOrInstance == null) { return "unknown"; } Class<?> cls = (classOrInstance instanceof Class<?>) ? (Class<?>) classOrInstance : classOrInstance.getClass(); return cls.getName(); } /* /********************************************************** /* Class loading /********************************************************** */ /** * @deprecated Since 2.6, use method in {@link com.fasterxml.jackson.databind.type.TypeFactory}. */

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.jsontype.impl; import java.util.*; import com.fasterxml.jackson.databind.AnnotationIntrospector; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.jsontype.SubtypeResolver; /** * Standard {@link SubtypeResolver} implementation. */ public class StdSubtypeResolver extends SubtypeResolver implements java.io.Serializable { private static final long serialVersionUID = 1L; protected LinkedHashSet<NamedType> _registeredSubtypes; public StdSubtypeResolver() { } /* /********************************************************** /* Subtype registration /********************************************************** */ @Override public void registerSubtypes(NamedType... types) { if (_registeredSubtypes == null) { _registeredSubtypes = new LinkedHashSet<NamedType>(); } for (NamedType type : types) { _registeredSubtypes.add(type); } } @Override public void registerSubtypes(Class<?>... classes) { NamedType[] types = new NamedType[classes.length]; for (int i = 0, len = classes.length; i < len; ++i) { types[i] = new NamedType(classes[i]); } registerSubtypes(types); } /* /********************************************************** /* Resolution by class (serialization) /********************************************************** */ @Override public Collection<NamedType> collectAndResolveSubtypesByClass(MapperConfig<?> config, AnnotatedMember property, JavaType baseType) { final AnnotationIntrospector ai = config.getAnnotationIntrospector(); // for backwards compatibility, must allow null here: Class<?> rawBase = (baseType == null) ? property.getRawType() : baseType.getRawClass(); HashMap<NamedType, NamedType> collected = new HashMap<NamedType, NamedType>(); // start with registered subtypes (which have precedence) if (_registeredSubtypes != null) { for (NamedType subtype : _registeredSubtypes) { // is it a subtype of root type? if (rawBase.isAssignableFrom(subtype.getType())) { // yes AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config); _collectAndResolve(curr, subtype, config, ai, collected); } } } // then annotated types for property itself Collection<NamedType> st = ai.findSubtypes(property); if (st != null

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>) { for (NamedType nt : st) { AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(nt.getType(), config); _collectAndResolve(ac, nt, config, ai, collected); } } NamedType rootType = new NamedType(rawBase, null); AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(rawBase, config); // and finally subtypes via annotations from base type (recursively) _collectAndResolve(ac, rootType, config, ai, collected); return new ArrayList<NamedType>(collected.values()); } @Override public Collection<NamedType> collectAndResolveSubtypesByClass(MapperConfig<?> config, AnnotatedClass type) { final AnnotationIntrospector ai = config.getAnnotationIntrospector(); HashMap<NamedType, NamedType> subtypes = new HashMap<NamedType, NamedType>(); // [JACKSON-257] then consider registered subtypes (which have precedence over annotations) if (_registeredSubtypes != null) { Class<?> rawBase = type.getRawType(); for (NamedType subtype : _registeredSubtypes) { // is it a subtype of root type? if (rawBase.isAssignableFrom(subtype.getType())) { // yes AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config); _collectAndResolve(curr, subtype, config, ai, subtypes); } } } // and then check subtypes via annotations from base type (recursively) NamedType rootType = new NamedType(type.getRawType(), null); _collectAndResolve(type, rootType, config, ai, subtypes); return new ArrayList<NamedType>(subtypes.values()); } /* /********************************************************** /* Resolution by class (deserialization) /********************************************************** */ @Override public Collection<NamedType> collectAndResolveSubtypesByTypeId(MapperConfig<?> config, AnnotatedMember property, JavaType baseType) { final AnnotationIntrospector ai = config.getAnnotationIntrospector(); Class<?> rawBase = (baseType == null) ? property.getRawType() : baseType.getRawClass(); // Need to keep track of classes that have been handled already Set<Class<?>> typesHandled = new HashSet<Class<?>>(); Map<String,NamedType> byName = new LinkedHashMap<String,NamedType>(); // start with lowest-precedence, which is from type hierarchy NamedType rootType = new NamedType(rawBase, null); AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(rawBase, config); _collectAndResolveByTypeId(ac, rootType

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>, config, typesHandled, byName); // then with definitions from property Collection<NamedType> st = ai.findSubtypes(property); if (st != null) { for (NamedType nt : st) { ac = AnnotatedClass.constructWithoutSuperTypes(nt.getType(), config); _collectAndResolveByTypeId(ac, nt, config, typesHandled, byName); } } // and finally explicit type registrations (highest precedence) if (_registeredSubtypes != null) { for (NamedType subtype : _registeredSubtypes) { // is it a subtype of root type? if (rawBase.isAssignableFrom(subtype.getType())) { // yes AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config); _collectAndResolveByTypeId(curr, subtype, config, typesHandled, byName); } } } return _combineNamedAndUnnamed(typesHandled, byName); } @Override public Collection<NamedType> collectAndResolveSubtypesByTypeId(MapperConfig<?> config, AnnotatedClass type) { Set<Class<?>> typesHandled = new HashSet<Class<?>>(); Map<String,NamedType> byName = new LinkedHashMap<String,NamedType>(); NamedType rootType = new NamedType(type.getRawType(), null); _collectAndResolveByTypeId(type, rootType, config, typesHandled, byName); if (_registeredSubtypes != null) { Class<?> rawBase = type.getRawType(); for (NamedType subtype : _registeredSubtypes) { // is it a subtype of root type? if (rawBase.isAssignableFrom(subtype.getType())) { // yes AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config); _collectAndResolveByTypeId(curr, subtype, config, typesHandled, byName); } } } return _combineNamedAndUnnamed(typesHandled, byName); } /* /********************************************************** /* Deprecated method overrides /********************************************************** */ @Override @Deprecated public Collection<NamedType> collectAndResolveSubtypes(AnnotatedMember property, MapperConfig<?> config, AnnotationIntrospector ai, JavaType baseType) { return collectAndResolveSubtypesByClass(config, property, baseType); } @Override @Deprecated public Collection<NamedType> collectAndResolveSubtypes(AnnotatedClass type, MapperConfig<?> config, AnnotationIntrospector ai) { return collectAndResolveSubtypesByClass(config, type); } /* /********************************************************** /* Internal methods /********************************************************** */ /** * Method called to find subtypes for

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>_ANT")); } /* /********************************************************** /* Parser/generator construction /********************************************************** */ protected JsonParser createParserUsingReader(String input) throws IOException, JsonParseException { return createParserUsingReader(new JsonFactory(), input); } protected JsonParser createParserUsingReader(JsonFactory f, String input) throws IOException, JsonParseException { return f.createParser(new StringReader(input)); } protected JsonParser createParserUsingStream(String input, String encoding) throws IOException, JsonParseException { return createParserUsingStream(new JsonFactory(), input, encoding); } protected JsonParser createParserUsingStream(JsonFactory f, String input, String encoding) throws IOException, JsonParseException { /* 23-Apr-2008, tatus: UTF-32 is not supported by JDK, have to * use our own codec too (which is not optimal since there's * a chance both encoder and decoder might have bugs, but ones * that cancel each other out or such) */ byte[] data; if (encoding.equalsIgnoreCase("UTF-32")) { data = encodeInUTF32BE(input); } else { data = input.getBytes(encoding); } InputStream is = new ByteArrayInputStream(data); return f.createParser(is); } /* /********************************************************** /* Additional assertion methods /********************************************************** */ protected void assertToken(JsonToken expToken, JsonToken actToken) { if (actToken != expToken) { fail("Expected token "+expToken+", current token "+actToken); } } protected void assertToken(JsonToken expToken, JsonParser jp) { assertToken(expToken, jp.getCurrentToken()); } protected void assertType(Object ob, Class<?> expType) { if (ob == null) { fail("Expected an object of type "+expType.getName()+", got null"); } Class<?> cls = ob.getClass(); if (!expType.isAssignableFrom(cls)) { fail("Expected type "+expType.getName()+", got "+cls.getName()); } } protected void assertValidLocation(JsonLocation location) { assertNotNull("Should have non-null location", location); assertTrue("Should have positive line number", location.getLineNr() > 0); } protected void verifyException(Throwable e, String... matches) { String msg = e.getMessage(); String lmsg = (msg == null) ? "" : msg.toLowerCase(); for (String match : matches) { String lmatch = match.toLowerCase(); if (lmsg.indexOf(lmatch) >=

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> } // also: verify that type is compatible JavaType referredType = _beanType; JavaType backRefType = backProp.getType(); boolean isContainer = prop.getType().isContainerType(); if (!backRefType.getRawClass().isAssignableFrom(referredType.getRawClass())) { throw new IllegalArgumentException("Can not handle managed/back reference '"+refName+"': back reference type (" +backRefType.getRawClass().getName()+") not compatible with managed type (" +referredType.getRawClass().getName()+")"); } return new ManagedReferenceProperty(prop, refName, backProp, _classAnnotations, isContainer); } /** * Method that wraps given property with {@link ObjectIdReferenceProperty} * in case where object id resolution is required. */ protected SettableBeanProperty _resolvedObjectIdProperty(DeserializationContext ctxt, SettableBeanProperty prop) { ObjectIdInfo objectIdInfo = prop.getObjectIdInfo(); JsonDeserializer<Object> valueDeser = prop.getValueDeserializer(); ObjectIdReader objectIdReader = valueDeser.getObjectIdReader(); if (objectIdInfo == null && objectIdReader == null) { return prop; } return new ObjectIdReferenceProperty(prop, objectIdInfo); } /** * Helper method called to see if given property might be so-called unwrapped * property: these require special handling. */ protected SettableBeanProperty _resolveUnwrappedProperty(DeserializationContext ctxt, SettableBeanProperty prop) { AnnotatedMember am = prop.getMember(); if (am != null) { NameTransformer unwrapper = ctxt.getAnnotationIntrospector().findUnwrappingNameTransformer(am); if (unwrapper != null) { JsonDeserializer<Object> orig = prop.getValueDeserializer(); JsonDeserializer<Object> unwrapping = orig.unwrappingDeserializer(unwrapper); if (unwrapping != orig && unwrapping != null) { // might be cleaner to create new instance; but difficult to do reliably, so: return prop.withValueDeserializer(unwrapping); } } } return null; } /** * Helper method that will handle gruesome details of dealing with properties * that have non-static inner class as value... */ protected SettableBeanProperty _resolveInnerClassValuedProperty(DeserializationContext ctxt, SettableBeanProperty prop) { /* Should we encounter a property that has non-static inner-class * as value, we need to add some more magic to find the "hidden" constructor... */ JsonDeserializer<Object> deser = prop.getValueDeserializer(); // ideally wouldn't rely on it being BeanDeserializerBase; but for now it'll have to do

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> if (deser instanceof BeanDeserializerBase) { BeanDeserializerBase bd = (BeanDeserializerBase) deser; ValueInstantiator vi = bd.getValueInstantiator(); if (!vi.canCreateUsingDefault()) { // no default constructor Class<?> valueClass = prop.getType().getRawClass(); Class<?> enclosing = ClassUtil.getOuterClass(valueClass); // and is inner class of the bean class... if (enclosing != null && enclosing == _beanType.getRawClass()) { for (Constructor<?> ctor : valueClass.getConstructors()) { Class<?>[] paramTypes = ctor.getParameterTypes(); if (paramTypes.length == 1 && paramTypes[0] == enclosing) { if (ctxt.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(ctor, ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } return new InnerClassProperty(prop, ctor); } } } } } return prop; } /* /********************************************************** /* Public accessors /********************************************************** */ @Override public boolean isCachable() { return true; } @Override public Class<?> handledType() { return _beanType.getRawClass(); } /** * Overridden to return true for those instances that are * handling value for which Object Identity handling is enabled * (either via value type or referring property). */ @Override public ObjectIdReader getObjectIdReader() { return _objectIdReader; } public boolean hasProperty(String propertyName) { return _beanProperties.find(propertyName) != null; } public boolean hasViews() { return _needViewProcesing; } /** * Accessor for checking number of deserialized properties. */ public int getPropertyCount() { return _beanProperties.size(); } @Override public Collection<Object> getKnownPropertyNames() { ArrayList<Object> names = new ArrayList<Object>(); for (SettableBeanProperty prop : _beanProperties) { names.add(prop.getName()); } return names; } /** * @deprecated Since 2.3, use {@link #handledType()} instead */ @Deprecated public final Class<?> getBeanClass() { return _beanType.getRawClass(); } @Override public JavaType getValueType() { return _beanType; } /** * Accessor for iterating over properties this deserializer uses; with * the exception that properties passed via Creator methods * (specifically, "property-based constructor") are not included, * but can be accessed separate by calling * {@link #creatorProperties} */ public Iterator<Set

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Exception.wrapWithPath(throwOrReturnThrowable(t, ctxt), bean, fieldName); } @Deprecated // since 2.4, not used by core Jackson; only relevant for arrays/Collections public void wrapAndThrow(Throwable t, Object bean, int index, DeserializationContext ctxt) throws IOException { // [JACKSON-55] Need to add reference information throw JsonMappingException.wrapWithPath(throwOrReturnThrowable(t, ctxt), bean, index); } private Throwable throwOrReturnThrowable(Throwable t, DeserializationContext ctxt) throws IOException { /* 05-Mar-2009, tatu: But one nasty edge is when we get * StackOverflow: usually due to infinite loop. But that * often gets hidden within an InvocationTargetException... */ while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors to be passed as is if (t instanceof Error) { throw (Error) t; } boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS); // Ditto for IOExceptions; except we may want to wrap JSON exceptions if (t instanceof IOException) { if (!wrap || !(t instanceof JsonProcessingException)) { throw (IOException) t; } } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions if (t instanceof RuntimeException) { throw (RuntimeException) t; } } return t; } protected void wrapInstantiationProblem(Throwable t, DeserializationContext ctxt) throws IOException { while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors and "plain" IOExceptions to be passed as is if (t instanceof Error) { throw (Error) t; } boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS); if (t instanceof IOException) { // Since we have no more information to add, let's not actually wrap.. throw (IOException) t; } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions if (t instanceof RuntimeException) { throw (RuntimeException) t; } } throw ctxt.instantiationException(_beanType.getRawClass(), t); } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> because Android (and presumably GAE) have these classes private final static Class<?> CLASS_DOM_NODE; private final static Class<?> CLASS_DOM_DOCUMENT; static { Class<?> doc = null, node = null; try { node = org.w3c.dom.Node.class; doc = org.w3c.dom.Document.class; } catch (Exception e) { // not optimal but will do System.err.println("WARNING: could not load DOM Node and/or Document classes"); } CLASS_DOM_NODE = node; CLASS_DOM_DOCUMENT = doc; } // // But Java7 type(s) may or may not be; dynamic lookup should be fine, still // // (note: also assume it comes from JDK so that ClassLoader issues with OSGi // // can, I hope, be avoided?) private final static Class<?> CLASS_JAVA7_PATH; static { Class<?> cls = null; try { cls = Class.forName("java.nio.file.Path"); } catch (Exception e) { // not optimal but will do System.err.println("WARNING: could not load Java7 Path class"); } CLASS_JAVA7_PATH = cls; } public final static OptionalHandlerFactory instance = new OptionalHandlerFactory(); protected OptionalHandlerFactory() { } /* /********************************************************** /* Public API /********************************************************** */ public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) { final Class<?> rawType = type.getRawClass(); if ((CLASS_JAVA7_PATH != null) && CLASS_JAVA7_PATH.isAssignableFrom(rawType)) { return ToStringSerializer.instance; } if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) { return (JsonSerializer<?>) instantiate(SERIALIZER_FOR_DOM_NODE); } String className = rawType.getName(); String factoryName; if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML) || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) { factoryName = SERIALIZERS_FOR_JAVAX_XML; } else { return null; } Object ob = instantiate(factoryName); if (ob == null) { // could warn, if we had logging system (j.u.l?) return null; } return ((Serializers) ob).findSerializer(config, type, beanDesc); } public JsonDeserializer<?> findDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> JsonMappingException { final Class<?> rawType = type.getRawClass(); if ((CLASS_JAVA7_PATH != null) && CLASS_JAVA7_PATH.isAssignableFrom(rawType)) { return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_PATH); } if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) { return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_NODE); } if ((CLASS_DOM_DOCUMENT != null) && CLASS_DOM_DOCUMENT.isAssignableFrom(rawType)) { return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT); } String className = rawType.getName(); String factoryName; if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML) || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) { factoryName = DESERIALIZERS_FOR_JAVAX_XML; } else { return null; } Object ob = instantiate(factoryName); if (ob == null) { // could warn, if we had logging system (j.u.l?) return null; } return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc); } /* /********************************************************** /* Internal helper methods /********************************************************** */ private Object instantiate(String className) { try { return Class.forName(className).newInstance(); } catch (LinkageError e) { } // too many different kinds to enumerate here: catch (Exception e) { } return null; } /** * Since 2.7 we only need to check for class extension, as all implemented * types are classes, not interfaces. This has performance implications for * some cases, as we do not need to go over interfaces implemented, just * superclasses * * @since 2.7 */ private boolean hasSuperClassStartingWith(Class<?> rawType, String prefix) { for (Class<?> supertype = rawType.getSuperclass(); supertype != null; supertype = supertype.getSuperclass()) { if (supertype == Object.class) { return false; } if (supertype.getName().startsWith(prefix)) { return true; } } return false; } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>SuppressWarnings("unchecked") public JsonSerializer<Object> findValueSerializer(JavaType valueType, BeanProperty property) throws JsonMappingException { // (see comments from above method) JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property); } /** * Method variant used when we do NOT want contextualization to happen; it will need * to be handled at a later point, but caller wants to be able to do that * as needed; sometimes to avoid infinite loops * * @since 2.5 */ public JsonSerializer<Object> findValueSerializer(Class<?> valueType) throws JsonMappingException { // (see comments from above method) JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType)); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } } } } } return ser; } /** * Method variant used when we do NOT want contextualization to happen; it will need * to be handled at a later point, but caller wants to be able to do that * as needed; sometimes to avoid infinite loops * * @since 2.5 */ public JsonSerializer<Object> findValueSerializer(JavaType valueType) throws JsonMappingException { // (see comments from above method) JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>valueType.getRawClass()); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } } } } return ser; } /** * Similar to {@link #findValueSerializer(JavaType, BeanProperty)}, but used * when finding "primary" property value serializer (one directly handling * value of the property). Difference has to do with contextual resolution, * and method(s) called: this method should only be called when caller is * certain that this is the primary property value serializer. * * @param property Property that is being handled; will never be null, and its * type has to match <code>valueType</code> parameter. * * @since 2.3 */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findPrimaryPropertySerializer(JavaType valueType, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property); } /** * @since 2.3 */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findPrimaryPropertySerializer(Class<?> valueType, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType)); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } } return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property); } /** * Method called to locate regular serializer, matching type serializer, *

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>.isPrimitive()) { Class<?> wrapperType = ClassUtil.wrapperType(rootType.getRawClass()); // If it's just difference between wrapper, primitive, let it slide if (wrapperType.isAssignableFrom(value.getClass())) { return; } } throw JsonMappingException.from(this, "Incompatible types: declared root type ("+rootType+") vs " +value.getClass().getName()); } /** * Method that will try to find a serializer, either from cache * or by constructing one; but will not return an "unknown" serializer * if this can not be done but rather returns null. * * @return Serializer if one can be found, null if not. */ protected JsonSerializer<Object> _findExplicitUntypedSerializer(Class<?> runtimeType) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(runtimeType); if (ser == null) { // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(runtimeType); if (ser == null) { ser = _createAndCacheUntypedSerializer(runtimeType); } } /* 18-Sep-2014, tatu: This is unfortunate patch over related change * that pushes creation of "unknown type" serializer deeper down * in BeanSerializerFactory; as a result, we need to "undo" creation * here. */ if (isUnknownTypeSerializer(ser)) { return null; } return ser; } /* /********************************************************** /* Low-level methods for actually constructing and initializing /* serializers /********************************************************** */ /** * Method that will try to construct a value serializer; and if * one is successfully created, cache it for reuse. */ protected JsonSerializer<Object> _createAndCacheUntypedSerializer(Class<?> rawType) throws JsonMappingException { JavaType fullType = _config.constructType(rawType); JsonSerializer<Object> ser; try { ser = _createUntypedSerializer(fullType); } catch (IllegalArgumentException iae) { /* We better only expose checked exceptions, since those * are what caller is expected to handle */ throw JsonMappingException.from(this, iae.getMessage(), iae); } if (ser != null) { // 21-Dec-2015, tatu: Best to cache for both raw and full-type key _serializerCache.addAndResolveNonTypedSerializer(rawType, fullType, ser, this); } return ser;

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> method used to create a copy with slightly * different settings. When sub-classing, MUST be overridden. */ @SuppressWarnings("unchecked") protected MapDeserializer withResolved(KeyDeserializer keyDeser, TypeDeserializer valueTypeDeser, JsonDeserializer<?> valueDeser, HashSet<String> ignorable) { if ((_keyDeserializer == keyDeser) && (_valueDeserializer == valueDeser) && (_valueTypeDeserializer == valueTypeDeser) && (_ignorableProperties == ignorable)) { return this; } return new MapDeserializer(this, keyDeser, (JsonDeserializer<Object>) valueDeser, valueTypeDeser, ignorable); } /** * Helper method used to check whether we can just use the default key * deserialization, where JSON String becomes Java String. */ protected final boolean _isStdKeyDeser(JavaType mapType, KeyDeserializer keyDeser) { if (keyDeser == null) { return true; } JavaType keyType = mapType.getKeyType(); if (keyType == null) { // assumed to be Object return true; } Class<?> rawKeyType = keyType.getRawClass(); return ((rawKeyType == String.class || rawKeyType == Object.class) && isDefaultKeyDeserializer(keyDeser)); } public void setIgnorableProperties(String[] ignorable) { _ignorableProperties = (ignorable == null || ignorable.length == 0) ? null : ArrayBuilders.arrayToSet(ignorable); } /* /********************************************************** /* Validation, post-processing (ResolvableDeserializer) /********************************************************** */ @Override public void resolve(DeserializationContext ctxt) throws JsonMappingException { // May need to resolve types for delegate- and/or property-based creators: if (_valueInstantiator.canCreateUsingDelegate()) { JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig()); if (delegateType == null) { throw new IllegalArgumentException("Invalid delegate-creator definition for "+_mapType +": value instantiator ("+_valueInstantiator.getClass().getName() +") returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'"); } /* Theoretically should be able to get CreatorProperty for delegate * parameter to pass; but things get tricky because DelegateCreator * may contain injectable values. So, for now, let's pass nothing. */ _delegateDeserializer = findDeserializer(ctxt, delegateType, null); } if (_valueInstantiator.canCreateFromObjectWith()) { SettableBeanProperty[] creatorProps = _valueInstantiator.getFromObjectArguments(ctxt.

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>NAME JsonToken t = p.getCurrentToken(); if (t != JsonToken.START_OBJECT && t != JsonToken.FIELD_NAME) { throw ctxt.mappingException(getMapClass()); } if (_standardStringKey) { _readAndBindStringMap(p, ctxt, result); return result; } _readAndBind(p, ctxt, result); return result; } @Override public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException, JsonProcessingException { // In future could check current token... for now this should be enough: return typeDeserializer.deserializeTypedFromObject(jp, ctxt); } /* /********************************************************** /* Other public accessors /********************************************************** */ @SuppressWarnings("unchecked") public final Class<?> getMapClass() { return (Class<Map<Object,Object>>) _mapType.getRawClass(); } @Override public JavaType getValueType() { return _mapType; } /* /********************************************************** /* Internal methods /********************************************************** */ protected final void _readAndBind(JsonParser p, DeserializationContext ctxt, Map<Object,Object> result) throws IOException { final KeyDeserializer keyDes = _keyDeserializer; final JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; MapReferringAccumulator referringAccumulator = null; boolean useObjectId = valueDes.getObjectIdReader() != null; if (useObjectId) { referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result); } String keyStr; if (p.isExpectedStartObjectToken()) { keyStr = p.nextFieldName(); } else { JsonToken t = p.getCurrentToken(); if (t == JsonToken.END_OBJECT) { return; } if (t != JsonToken.FIELD_NAME) { throw ctxt.mappingException(_mapType.getRawClass(), p.getCurrentToken()); } keyStr = p.getCurrentName(); } for (; keyStr != null; keyStr = p.nextFieldName()) { Object key = keyDes.deserializeKey(keyStr, ctxt); // And then the value... JsonToken t = p.nextToken(); if (_ignorableProperties != null && _ignorableProperties.contains(keyStr)) { p.skipChildren(); continue; } try { // Note: must handle null explicitly here; value deserializers won't Object value; if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(ctxt); } else if (typeDeser ==

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> null) { value = valueDes.deserialize(p, ctxt); } else { value = valueDes.deserializeWithType(p, ctxt, typeDeser); } if (useObjectId) { referringAccumulator.put(key, value); } else { result.put(key, value); } } catch (UnresolvedForwardReference reference) { handleUnresolvedReference(p, referringAccumulator, key, reference); } catch (Exception e) { wrapAndThrow(e, result, keyStr); } } } /** * Optimized method used when keys can be deserialized as plain old * {@link java.lang.String}s, and there is no custom deserialized * specified. */ protected final void _readAndBindStringMap(JsonParser p, DeserializationContext ctxt, Map<Object,Object> result) throws IOException { final JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; MapReferringAccumulator referringAccumulator = null; boolean useObjectId = (valueDes.getObjectIdReader() != null); if (useObjectId) { referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result); } String key; if (p.isExpectedStartObjectToken()) { key = p.nextFieldName(); } else { JsonToken t = p.getCurrentToken(); if (t == JsonToken.END_OBJECT) { return; } if (t != JsonToken.FIELD_NAME) { throw ctxt.mappingException(_mapType.getRawClass(), p.getCurrentToken()); } key = p.getCurrentName(); } for (; key != null; key = p.nextFieldName()) { JsonToken t = p.nextToken(); if (_ignorableProperties != null && _ignorableProperties.contains(key)) { p.skipChildren(); continue; } try { // Note: must handle null explicitly here; value deserializers won't Object value; if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(ctxt); } else if (typeDeser == null) { value = valueDes.deserialize(p, ctxt); } else { value = valueDes.deserializeWithType(p, ctxt, typeDeser); } if (useObjectId) { referringAccumulator.put(key, value); } else { result.put(key, value); } } catch (UnresolvedForwardReference reference) { handleUnresolvedReference(p, referringAccumulator, key, reference); } catch (Exception e) { wrapAndThrow(e, result,

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> key); } } // 23-Mar-2015, tatu: TODO: verify we got END_OBJECT? } @SuppressWarnings("unchecked") public Map<Object,Object> _deserializeUsingCreator(JsonParser p, DeserializationContext ctxt) throws IOException { final PropertyBasedCreator creator = _propertyBasedCreator; // null -> no ObjectIdReader for Maps (yet?) PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, null); final JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; String key; if (p.isExpectedStartObjectToken()) { key = p.nextFieldName(); } else if (p.hasToken(JsonToken.FIELD_NAME)) { key = p.getCurrentName(); } else { key = null; } for (; key != null; key = p.nextFieldName()) { JsonToken t = p.nextToken(); // to get to value if (_ignorableProperties != null && _ignorableProperties.contains(key)) { p.skipChildren(); // and skip it (in case of array/object) continue; } // creator property? SettableBeanProperty prop = creator.findCreatorProperty(key); if (prop != null) { // Last property to set? if (buffer.assignParameter(prop, prop.deserialize(p, ctxt))) { p.nextToken(); Map<Object,Object> result; try { result = (Map<Object,Object>)creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _mapType.getRawClass(), key); return null; } _readAndBind(p, ctxt, result); return result; } continue; } // other property? needs buffering Object actualKey = _keyDeserializer.deserializeKey(key, ctxt); Object value; try { if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(ctxt); } else if (typeDeser == null) { value = valueDes.deserialize(p, ctxt); } else { value = valueDes.deserializeWithType(p, ctxt, typeDeser); } } catch (Exception e) { wrapAndThrow(e, _mapType.getRawClass(), key); return null; } buffer.bufferMapProperty(actualKey, value); } // end of JSON object? // if so, can just construct and leave... try { return (Map<Object,Object>)creator.build(ctxt, buffer); } catch (Exception e) {

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> wrapAndThrow(e, _mapType.getRawClass(), key); return null; } } @Deprecated // since 2.5 protected void wrapAndThrow(Throwable t, Object ref) throws IOException { wrapAndThrow(t, ref, null); } private void handleUnresolvedReference(JsonParser jp, MapReferringAccumulator accumulator, Object key, UnresolvedForwardReference reference) throws JsonMappingException { if (accumulator == null) { throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference); } Referring referring = accumulator.handleUnresolvedReference(reference, key); reference.getRoid().appendReferring(referring); } private final static class MapReferringAccumulator { private final Class<?> _valueType; private Map<Object,Object> _result; /** * A list of {@link MapReferring} to maintain ordering. */ private List<MapReferring> _accumulator = new ArrayList<MapReferring>(); public MapReferringAccumulator(Class<?> valueType, Map<Object, Object> result) { _valueType = valueType; _result = result; } public void put(Object key, Object value) { if (_accumulator.isEmpty()) { _result.put(key, value); } else { MapReferring ref = _accumulator.get(_accumulator.size() - 1); ref.next.put(key, value); } } public Referring handleUnresolvedReference(UnresolvedForwardReference reference, Object key) { MapReferring id = new MapReferring(this, reference, _valueType, key); _accumulator.add(id); return id; } public void resolveForwardReference(Object id, Object value) throws IOException { Iterator<MapReferring> iterator = _accumulator.iterator(); // Resolve ordering after resolution of an id. This means either: // 1- adding to the result map in case of the first unresolved id. // 2- merge the content of the resolved id with its previous unresolved id. Map<Object,Object> previous = _result; while (iterator.hasNext()) { MapReferring ref = iterator.next(); if (ref.hasId(id)) { iterator.remove(); previous.put(ref.key, value); previous.putAll(ref.next); return; } previous = ref.next; } throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id + "] that wasn't previously seen as unresolved."); } } /** * Helper class to maintain processing order of value. * The resolved

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>) { BasicBeanDescription desc = _findStdTypeDesc(type); if (desc == null) { // As per [Databind#550], skip full introspection for some of standard // structured types as well desc = _findStdJdkCollectionDesc(cfg, type); if (desc == null) { desc = BasicBeanDescription.forDeserialization( collectProperties(cfg, type, r, false, "set")); } } // should this be cached for FCA? return desc; } @Override public BasicBeanDescription forClassAnnotations(MapperConfig<?> config, JavaType type, MixInResolver r) { BasicBeanDescription desc = _findStdTypeDesc(type); if (desc == null) { desc = _cachedFCA.get(type); if (desc == null) { AnnotatedClass ac = AnnotatedClass.construct(type, config, r); desc = BasicBeanDescription.forOtherUse(config, type, ac); _cachedFCA.put(type, desc); } } return desc; } @Override public BasicBeanDescription forDirectClassAnnotations(MapperConfig<?> config, JavaType type, MixInResolver r) { BasicBeanDescription desc = _findStdTypeDesc(type); if (desc == null) { AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(type.getRawClass(), config, r); desc = BasicBeanDescription.forOtherUse(config, type, ac); } return desc; } /* /********************************************************** /* Overridable helper methods /********************************************************** */ protected POJOPropertiesCollector collectProperties(MapperConfig<?> config, JavaType type, MixInResolver r, boolean forSerialization, String mutatorPrefix) { AnnotatedClass ac = AnnotatedClass.construct(type, config, r); return constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix); } protected POJOPropertiesCollector collectPropertiesWithBuilder(MapperConfig<?> config, JavaType type, MixInResolver r, boolean forSerialization) { boolean useAnnotations = config.isAnnotationProcessingEnabled(); AnnotationIntrospector ai = useAnnotations ? config.getAnnotationIntrospector() : null; AnnotatedClass ac = AnnotatedClass.construct(type, config, r); JsonPOJOBuilder.Value builderConfig = (ai == null) ? null : ai.findPOJOBuilderConfig(ac); String mutatorPrefix = (builderConfig == null) ? "with" : builderConfig.withPrefix; return constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix); }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> /** * Overridable method called for creating {@link POJOPropertiesCollector} instance * to use; override is needed if a custom sub-class is to be used. */ protected POJOPropertiesCollector constructPropertyCollector(MapperConfig<?> config, AnnotatedClass ac, JavaType type, boolean forSerialization, String mutatorPrefix) { return new POJOPropertiesCollector(config, forSerialization, type, ac, mutatorPrefix); } /** * Method called to see if type is one of core JDK types * that we have cached for efficiency. */ protected BasicBeanDescription _findStdTypeDesc(JavaType type) { Class<?> cls = type.getRawClass(); if (cls.isPrimitive()) { if (cls == Boolean.TYPE) { return BOOLEAN_DESC; } if (cls == Integer.TYPE) { return INT_DESC; } if (cls == Long.TYPE) { return LONG_DESC; } } else { if (cls == String.class) { return STRING_DESC; } } return null; } /** * Helper method used to decide whether we can omit introspection * for members (methods, fields, constructors); we may do so for * a limited number of container types JDK provides. */ protected boolean _isStdJDKCollection(JavaType type) { if (!type.isContainerType() || type.isArrayType()) { return false; } Class<?> raw = type.getRawClass(); String pkgName = ClassUtil.getPackageName(raw); if (pkgName != null) { if (pkgName.startsWith("java.lang") || pkgName.startsWith("java.util")) { /* 23-Sep-2014, tatu: Should we be conservative here (minimal number * of matches), or ambitious? Let's do latter for now. */ if (Collection.class.isAssignableFrom(raw) || Map.class.isAssignableFrom(raw)) { return true; } } } return false; } protected BasicBeanDescription _findStdJdkCollectionDesc(MapperConfig<?> cfg, JavaType type) { if (_isStdJDKCollection(type)) { AnnotatedClass ac = AnnotatedClass.construct(type, cfg); return BasicBeanDescription.forOtherUse(cfg, type, ac); } return null; } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.deser; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader; import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; /** * Deserializer only used for abstract types used as placeholders during polymorphic * type handling deserialization. If so, there is no real deserializer associated * with nominal type, just {@link TypeDeserializer}; and any calls that do not * pass such resolver will result in an error. */ public class AbstractDeserializer extends JsonDeserializer<Object> implements java.io.Serializable { private static final long serialVersionUID = 1L; protected final JavaType _baseType; protected final ObjectIdReader _objectIdReader; protected final Map<String, SettableBeanProperty> _backRefProperties; // support for "native" types, which require special care: protected final boolean _acceptString; protected final boolean _acceptBoolean; protected final boolean _acceptInt; protected final boolean _acceptDouble; public AbstractDeserializer(BeanDeserializerBuilder builder, BeanDescription beanDesc, Map<String, SettableBeanProperty> backRefProps) { _baseType = beanDesc.getType(); _objectIdReader = builder.getObjectIdReader(); _backRefProperties = backRefProps; Class<?> cls = _baseType.getRawClass(); _acceptString = cls.isAssignableFrom(String.class); _acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class); _acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class); _acceptDouble = (cls == Double.TYPE) || cls.isAssignableFrom(Double.class); } protected AbstractDeserializer(BeanDescription beanDesc) { _baseType = beanDesc.getType(); _objectIdReader = null; _backRefProperties = null; Class<?> cls = _baseType.getRawClass(); _acceptString = cls.isAssignableFrom(String.class); _acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class); _acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class); _acceptDouble = (cls == Double.TYPE) || cls.isAssignableFrom(Double.class); } /** * Factory method used when constructing instances for non-POJO types, like * {@link java.util.Map}s. * * @since 2.3 */

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> public static AbstractDeserializer constructForNonPOJO(BeanDescription beanDesc) { return new AbstractDeserializer(beanDesc); } /* /********************************************************** /* Public accessors /********************************************************** */ @Override public Class<?> handledType() { return _baseType.getRawClass(); } @Override public boolean isCachable() { return true; } /** * Overridden to return true for those instances that are * handling value for which Object Identity handling is enabled * (either via value type or referring property). */ @Override public ObjectIdReader getObjectIdReader() { return _objectIdReader; } /** * Method called by <code>BeanDeserializer</code> to resolve back reference * part of managed references. */ @Override public SettableBeanProperty findBackReference(String logicalName) { return (_backRefProperties == null) ? null : _backRefProperties.get(logicalName); } /* /********************************************************** /* Deserializer implementation /********************************************************** */ @Override public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException { // Hmmh. One tricky question; for scalar, is it an Object Id, or "Natural" type? // for now, prefer Object Id: if (_objectIdReader != null) { JsonToken t = p.getCurrentToken(); if (t != null) { // Most commonly, a scalar (int id, uuid String, ...) if (t.isScalarValue()) { return _deserializeFromObjectId(p, ctxt); } // but, with 2.5+, a simple Object-wrapped value also legal: if (t == JsonToken.START_OBJECT) { t = p.nextToken(); } if ((t == JsonToken.FIELD_NAME) && _objectIdReader.maySerializeAsObject() && _objectIdReader.isValidReferencePropertyName(p.getCurrentName(), p)) { return _deserializeFromObjectId(p, ctxt); } } } // First: support "natural" values (which are always serialized without type info!) Object result = _deserializeIfNatural(p, ctxt); if (result != null) { return result; } return typeDeserializer.deserializeTypedFromObject(p, ctxt); } @Override public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // This method should never be called... throw ctxt.instantiationException(_baseType.getRawClass(), "abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information"); } /* /********************************************************** /* Internal methods

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> return new SimpleType(raw, null, // 18-Oct-2015, tatu: Should be ok to omit possible super-types, right? null, null, null, null, false); } /** * Method that should NOT to be used by application code: * it does NOT properly handle inspection of super-types, so neither parent * Classes nor implemented Interfaces are accessible with resulting type * instance. Instead, please use {@link TypeFactory}'s <code>constructType</code> * methods which handle introspection appropriately. *<p> * Note that prior to 2.7, method usage was not limited and would typically * have worked acceptably: the problem comes from inability to resolve super-type * information, for which {@link TypeFactory} is needed. * * @deprecated Since 2.7 */ @Deprecated public static SimpleType construct(Class<?> cls) { /* Let's add sanity checks, just to ensure no * Map/Collection entries are constructed */ if (Map.class.isAssignableFrom(cls)) { throw new IllegalArgumentException("Can not construct SimpleType for a Map (class: "+cls.getName()+")"); } if (Collection.class.isAssignableFrom(cls)) { throw new IllegalArgumentException("Can not construct SimpleType for a Collection (class: "+cls.getName()+")"); } // ... and while we are at it, not array types either if (cls.isArray()) { throw new IllegalArgumentException("Can not construct SimpleType for an array (class: "+cls.getName()+")"); } TypeBindings b = TypeBindings.emptyBindings(); return new SimpleType(cls, b, _buildSuperClass(cls.getSuperclass(), b), null, null, null, false); } @Override @Deprecated protected JavaType _narrow(Class<?> subclass) { if (_class == subclass) { return this; } // Should we check that there is a sub-class relationship? // 15-Jan-2016, tatu: Almost yes, but there are some complications with // placeholder values (`Void`, `NoClass`), so can not quite do yet. // TODO: fix in 2.8 if (!_class.isAssignableFrom(subclass)) { /* throw new IllegalArgumentException("Class "+subclass.getName()+" not sub-type of " +_class.getName()); */ return new SimpleType(subclass, _bindings, this, _superInterfaces, _valueHandler, _typeHandler, _asStatic); } // Otherwise, stitch together the hierarchy. First, super-class Class<?> next = subclass.getSuperclass(); if

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> (next == _class) { // straight up parent class? Great. return new SimpleType(subclass, _bindings, this, _superInterfaces, _valueHandler, _typeHandler, _asStatic); } if ((next != null) && _class.isAssignableFrom(next)) { JavaType superb = _narrow(next); return new SimpleType(subclass, _bindings, superb, null, _valueHandler, _typeHandler, _asStatic); } // if not found, try a super-interface Class<?>[] nextI = subclass.getInterfaces(); for (Class<?> iface : nextI) { if (iface == _class) { // directly implemented return new SimpleType(subclass, _bindings, null, new JavaType[] { this }, _valueHandler, _typeHandler, _asStatic); } if (_class.isAssignableFrom(iface)) { // indirect, so recurse JavaType superb = _narrow(iface); return new SimpleType(subclass, _bindings, null, new JavaType[] { superb }, _valueHandler, _typeHandler, _asStatic); } } // should not get here but... throw new IllegalArgumentException("Internal error: Can not resolve sub-type for Class "+subclass.getName()+" to " +_class.getName()); } @Override public JavaType withContentType(JavaType contentType) { throw new IllegalArgumentException("Simple types have no content types; can not call withContentType()"); } @Override public SimpleType withTypeHandler(Object h) { if (_typeHandler == h) { return this; } return new SimpleType(_class, _bindings, _superClass, _superInterfaces, _valueHandler, h, _asStatic); } @Override public JavaType withContentTypeHandler(Object h) { // no content type, so: throw new IllegalArgumentException("Simple types have no content types; can not call withContenTypeHandler()"); } @Override public SimpleType withValueHandler(Object h) { if (h == _valueHandler) { return this; } return new SimpleType(_class, _bindings, _superClass, _superInterfaces, h, _typeHandler, _asStatic); } @Override public SimpleType withContentValueHandler(Object h) { // no content type, so: throw new IllegalArgumentException("Simple types have no content types; can not call withContenValueHandler()"); } @Override public SimpleType withStaticTyping() { return _asStatic ? this : new SimpleType(_class, _bindings, _superClass, _superInterfaces, _valueHandler, _typeHandler, true); } @Override public Java

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> new POJOPropertyBuilder(_config, _annotationIntrospector, _forSerialization, PropertyName.construct(implName)); props.put(implName, prop); } return prop; } private PropertyNamingStrategy _findNamingStrategy() { Object namingDef = (_annotationIntrospector == null)? null : _annotationIntrospector.findNamingStrategy(_classDef); if (namingDef == null) { return _config.getPropertyNamingStrategy(); } if (namingDef instanceof PropertyNamingStrategy) { return (PropertyNamingStrategy) namingDef; } /* Alas, there's no way to force return type of "either class * X or Y" -- need to throw an exception after the fact */ if (!(namingDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned PropertyNamingStrategy definition of type " +namingDef.getClass().getName()+"; expected type PropertyNamingStrategy or Class<PropertyNamingStrategy> instead"); } Class<?> namingClass = (Class<?>)namingDef; // 09-Nov-2015, tatu: Need to consider pseudo-value of STD, which means "use default" if (namingClass == PropertyNamingStrategy.class) { return null; } if (!PropertyNamingStrategy.class.isAssignableFrom(namingClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class " +namingClass.getName()+"; expected Class<PropertyNamingStrategy>"); } HandlerInstantiator hi = _config.getHandlerInstantiator(); if (hi != null) { PropertyNamingStrategy pns = hi.namingStrategyInstance(_config, _classDef, namingClass); if (pns != null) { return pns; } } return (PropertyNamingStrategy) ClassUtil.createInstance(namingClass, _config.canOverrideAccessModifiers()); } protected void _updateCreatorProperty(POJOPropertyBuilder prop, List<POJOPropertyBuilder> creatorProperties) { if (creatorProperties != null) { for (int i = 0, len = creatorProperties.size(); i < len; ++i) { if (creatorProperties.get(i).getInternalName().equals(prop.getInternalName())) { creatorProperties.set(i, prop); break; } } } } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> superInterfaces, _elementType, _valueHandler, _typeHandler, _asStatic); } /* /********************************************************** /* Public API /********************************************************** */ @Override public boolean isContainerType() { return true; } @Override public boolean isCollectionLikeType() { return true; } @Override public JavaType getContentType() { return _elementType; } @Override public Object getContentValueHandler() { return _elementType.getValueHandler(); } @Override public Object getContentTypeHandler() { return _elementType.getTypeHandler(); } @Override public StringBuilder getErasedSignature(StringBuilder sb) { return _classSignature(_class, sb, true); } @Override public StringBuilder getGenericSignature(StringBuilder sb) { _classSignature(_class, sb, false); sb.append('<'); _elementType.getGenericSignature(sb); sb.append(">;"); return sb; } @Override protected String buildCanonicalName() { StringBuilder sb = new StringBuilder(); sb.append(_class.getName()); if (_elementType != null) { sb.append('<'); sb.append(_elementType.toCanonical()); sb.append('>'); } return sb.toString(); } /* /********************************************************** /* Extended API /********************************************************** */ /** * Method that can be used for checking whether this type is a * "real" Collection type; meaning whether it represents a parameterized * subtype of {@link java.util.Collection} or just something that acts * like one. */ public boolean isTrueCollectionType() { return Collection.class.isAssignableFrom(_class); } /* /********************************************************** /* Standard methods /********************************************************** */ @Override public boolean equals(Object o) { if (o == this) return true; if (o == null) return false; if (o.getClass() != getClass()) return false; CollectionLikeType other = (CollectionLikeType) o; return (_class == other._class) && _elementType.equals(other._elementType); } @Override public String toString() { return "[collection-like type; class "+_class.getName()+", contains "+_elementType+"]"; } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> able to optimize bit more in future... return defaultInstance().constructType(t).getRawClass(); } /* /********************************************************** /* Low-level helper methods /********************************************************** */ /** * Low-level lookup method moved from {@link com.fasterxml.jackson.databind.util.ClassUtil}, * to allow for overriding of lookup functionality in environments like OSGi. * * @since 2.6 */ public Class<?> findClass(String className) throws ClassNotFoundException { if (className.indexOf('.') < 0) { Class<?> prim = _findPrimitive(className); if (prim != null) { return prim; } } // Two-phase lookup: first using context ClassLoader; then default Throwable prob = null; ClassLoader loader = this.getClassLoader(); if (loader == null) { loader = Thread.currentThread().getContextClassLoader(); } if (loader != null) { try { return classForName(className, true, loader); } catch (Exception e) { prob = ClassUtil.getRootCause(e); } } try { return classForName(className); } catch (Exception e) { if (prob == null) { prob = ClassUtil.getRootCause(e); } } if (prob instanceof RuntimeException) { throw (RuntimeException) prob; } throw new ClassNotFoundException(prob.getMessage(), prob); } protected Class<?> classForName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException { return Class.forName(name, true, loader); } protected Class<?> classForName(String name) throws ClassNotFoundException { return Class.forName(name); } protected Class<?> _findPrimitive(String className) { if ("int".equals(className)) return Integer.TYPE; if ("long".equals(className)) return Long.TYPE; if ("float".equals(className)) return Float.TYPE; if ("double".equals(className)) return Double.TYPE; if ("boolean".equals(className)) return Boolean.TYPE; if ("byte".equals(className)) return Byte.TYPE; if ("char".equals(className)) return Character.TYPE; if ("short".equals(className)) return Short.TYPE; if ("void".equals(className)) return Void.TYPE; return null; } /* /********************************************************** /* Type conversion, parameterization resolution methods /********************************************************** */ /** * Factory method for creating a subtype of given base type, as defined * by specified subclass; but retaining generic type information if any. * Can be used, for example, to get equivalent of "HashMap&lt;String,

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Integer&gt;" * from "Map&lt;String,Integer&gt;" by giving <code>HashMap.class</code> * as subclass. */ public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) { // simple optimization to avoid costly introspection if type-erased type does NOT differ final Class<?> rawBase = baseType.getRawClass(); if (rawBase == subclass) { return baseType; } JavaType newType; // also: if we start from untyped, not much to save do { // bogus loop to be able to break if (rawBase == Object.class) { newType = _fromClass(null, subclass, TypeBindings.emptyBindings()); break; } if (!rawBase.isAssignableFrom(subclass)) { throw new IllegalArgumentException(String.format( "Class %s not subtype of %s", subclass.getName(), baseType)); } // A few special cases where we can simplify handling: // (1) Original target type has no generics -- just resolve subtype if (baseType.getBindings().isEmpty()) { newType = _fromClass(null, subclass, TypeBindings.emptyBindings()); break; } // (2) A small set of "well-known" List/Map subtypes where can take a short-cut if (baseType.isContainerType()) { if (baseType.isMapLikeType()) { if ((subclass == HashMap.class) || (subclass == LinkedHashMap.class) || (subclass == EnumMap.class) || (subclass == TreeMap.class)) { newType = _fromClass(null, subclass, TypeBindings.create(subclass, baseType.getKeyType(), baseType.getContentType())); break; } } else if (baseType.isCollectionLikeType()) { if ((subclass == ArrayList.class) || (subclass == LinkedList.class) || (subclass == HashSet.class) || (subclass == TreeSet.class)) { newType = _fromClass(null, subclass, TypeBindings.create(subclass, baseType.getContentType())); break; } // 29-Oct-2015, tatu: One further shortcut: there are variants of `EnumSet`, // but they are impl details and we basically do not care... if (rawBase == EnumSet.class) { return baseType; } } } // (3) Sub-class does not take type parameters -- just resolve subtype int typeParamCount = subclass.getTypeParameters().length; if (typeParamCount == 0) { newType = _fromClass(

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>.class.isAssignableFrom(subclass) || Collection.class.isAssignableFrom(subclass)) { // need to assert type compatibility... if (!baseType.getRawClass().isAssignableFrom(subclass)) { throw new IllegalArgumentException("Class "+subclass.getClass().getName()+" not subtype of "+baseType); } // this _should_ work, right? JavaType subtype = _fromClass(null, subclass, TypeBindings.emptyBindings()); // one more thing: handlers to copy? Object h = baseType.getValueHandler(); if (h != null) { subtype = subtype.withValueHandler(h); } h = baseType.getTypeHandler(); if (h != null) { subtype = subtype.withTypeHandler(h); } return subtype; } } // But there is the need for special case for arrays too, it seems if (baseType instanceof ArrayType) { if (subclass.isArray()) { // actually see if it might be a no-op first: ArrayType at = (ArrayType) baseType; Class<?> rawComp = subclass.getComponentType(); if (at.getContentType().getRawClass() == rawComp) { return baseType; } JavaType componentType = _fromAny(null, rawComp, null); return ((ArrayType) baseType).withComponentType(componentType); } } // otherwise regular narrowing should work just fine return baseType.narrowBy(subclass); */ } /** * Method similar to {@link #constructSpecializedType}, but that creates a * less-specific type of given type. Usually this is as simple as simply * finding super-type with type erasure of <code>superClass</code>, but * there may be need for some additional work-arounds. * * @param superClass * * @since 2.7 */ public JavaType constructGeneralizedType(JavaType baseType, Class<?> superClass) { // simple optimization to avoid costly introspection if type-erased type does NOT differ final Class<?> rawBase = baseType.getRawClass(); if (rawBase == superClass) { return baseType; } JavaType superType = baseType.findSuperType(superClass); if (superType == null) { // Most likely, caller did not verify sub/super-type relationship if (!superClass.isAssignableFrom(rawBase)) { throw new IllegalArgumentException(String.format( "Class %s not a super-type of %s", superClass.getName(), baseType)); } // 01-Nov-2015, tatu: Should never happen, but ch throw new IllegalArgumentException(String.format( "Internal error

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>: class %s not included as super-type for %s", superClass.getName(), baseType)); } return superType; } /** * Factory method for constructing a {@link JavaType} out of its canonical * representation (see {@link JavaType#toCanonical()}). * * @param canonical Canonical string representation of a type * * @throws IllegalArgumentException If canonical representation is malformed, * or class that type represents (including its generic parameters) is * not found */ public JavaType constructFromCanonical(String canonical) throws IllegalArgumentException { return _parser.parse(canonical); } /** * Method that is to figure out actual type parameters that given * class binds to generic types defined by given (generic) * interface or class. * This could mean, for example, trying to figure out * key and value types for Map implementations. * * @param type Sub-type (leaf type) that implements <code>expType</code> */ public JavaType[] findTypeParameters(JavaType type, Class<?> expType) { JavaType match = type.findSuperType(expType); if (match == null) { return NO_TYPES; } return match.getBindings().typeParameterArray(); } /** * @deprecated Since 2.7 resolve raw type first, then find type parameters */ @Deprecated // since 2.7 public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType, TypeBindings bindings) { return findTypeParameters(constructType(clz, bindings), expType); } /** * @deprecated Since 2.7 resolve raw type first, then find type parameters */ @Deprecated // since 2.7 public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType) { return findTypeParameters(constructType(clz), expType); } /** * Method that can be called to figure out more specific of two * types (if they are related; that is, one implements or extends the * other); or if not related, return the primary type. * * @param type1 Primary type to consider * @param type2 Secondary type to consider * * @since 2.2 */ public JavaType moreSpecificType(JavaType type1, JavaType type2) { if (type1 == null) { return type2; } if (type2 == null) { return type1; } Class<?> raw1 = type1.getRawClass(); Class<?> raw2 = type2.getRawClass(); if (raw1 == raw2) { return type1

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>; } // TODO: maybe try sub-classing, to retain generic types? if (raw1.isAssignableFrom(raw2)) { return type2; } return type1; } /* /********************************************************** /* Public factory methods /********************************************************** */ public JavaType constructType(Type type) { return _fromAny(null, type, EMPTY_BINDINGS); } public JavaType constructType(Type type, TypeBindings bindings) { return _fromAny(null, type, bindings); } public JavaType constructType(TypeReference<?> typeRef) { // 19-Oct-2015, tatu: Simpler variant like so should work return _fromAny(null, typeRef.getType(), EMPTY_BINDINGS); // but if not, due to funky sub-classing, type variables, what follows // is a more complete processing a la Java ClassMate. /* final Class<?> refdRawType = typeRef.getClass(); JavaType type = _fromClass(null, refdRawType, EMPTY_BINDINGS); JavaType genType = type.findSuperType(TypeReference.class); if (genType == null) { // sanity check; shouldn't occur throw new IllegalArgumentException("Unparameterized GenericType instance ("+refdRawType.getName()+")"); } TypeBindings b = genType.getBindings(); JavaType[] params = b.typeParameterArray(); if (params.length == 0) { throw new IllegalArgumentException("Unparameterized GenericType instance ("+refdRawType.getName()+")"); } return params[0]; */ } /** * @deprecated Since 2.7 (accidentally removed in 2.7.0; added back in 2.7.1) */ @Deprecated public JavaType constructType(Type type, Class<?> contextClass) { TypeBindings bindings = (contextClass == null) ? TypeBindings.emptyBindings() : constructType(contextClass).getBindings(); return _fromAny(null, type, bindings); } /** * @deprecated Since 2.7 (accidentally removed in 2.7.0; added back in 2.7.1) */ @Deprecated public JavaType constructType(Type type, JavaType contextType) { TypeBindings bindings = (contextType == null) ? TypeBindings.emptyBindings() : contextType.getBindings(); return _fromAny(null, type, bindings); } /* /********************************************************** /* Direct factory methods /********************************************************** */ /** * Method for constructing an {@link ArrayType}. *<p

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>BeanType(type.getRawClass())) { return null; } // Use generic bean introspection to build deserializer return buildBeanDeserializer(ctxt, type, beanDesc); } @Override public JsonDeserializer<Object> createBuilderBasedDeserializer( DeserializationContext ctxt, JavaType valueType, BeanDescription beanDesc, Class<?> builderClass) throws JsonMappingException { // First: need a BeanDescription for builder class JavaType builderType = ctxt.constructType(builderClass); BeanDescription builderDesc = ctxt.getConfig().introspectForBuilder(builderType); return buildBuilderBasedDeserializer(ctxt, valueType, builderDesc); } /** * Method called by {@link BeanDeserializerFactory} to see if there might be a standard * deserializer registered for given type. */ protected JsonDeserializer<?> findStdDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { // note: we do NOT check for custom deserializers here, caller has already // done that JsonDeserializer<?> deser = findDefaultDeserializer(ctxt, type, beanDesc); // Also: better ensure these are post-processable? if (deser != null) { if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyDeserializer(ctxt.getConfig(), beanDesc, deser); } } } return deser; } protected JavaType materializeAbstractType(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { // May have multiple resolvers, call in precedence order until one returns non-null for (AbstractTypeResolver r : _factoryConfig.abstractTypeResolvers()) { JavaType concrete = r.resolveAbstractType(ctxt.getConfig(), beanDesc); if (concrete != null) { return concrete; } } return null; } /* /********************************************************** /* Public construction method beyond DeserializerFactory API: /* can be called from outside as well as overridden by /* sub-classes /********************************************************** */ /** * Method that is to actually build a bean deserializer instance. * All basic sanity checks have been done to know that what we have * may be a valid bean type, and that there are no default simple * deserializers. */ @SuppressWarnings("unchecked") public JsonDeserializer<Object> buildBeanDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { // First: check what creators we can use, if any ValueInstantiator valueInstantiator; /* 04-Jun-20

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> propDef.getGetter(); // should only consider Collections and Maps, for now? Class<?> rawPropertyType = getter.getRawType(); if (Collection.class.isAssignableFrom(rawPropertyType) || Map.class.isAssignableFrom(rawPropertyType)) { prop = constructSetterlessProperty(ctxt, beanDesc, propDef); } } // 25-Sep-2014, tatu: No point in finding constructor parameters for abstract types // (since they are never used anyway) if (isConcrete && propDef.hasConstructorParameter()) { /* [JACKSON-700] If property is passed via constructor parameter, we must * handle things in special way. Not sure what is the most optimal way... * for now, let's just call a (new) method in builder, which does nothing. */ // but let's call a method just to allow custom builders to be aware... final String name = propDef.getName(); CreatorProperty cprop = null; if (creatorProps != null) { for (SettableBeanProperty cp : creatorProps) { if (name.equals(cp.getName()) && (cp instanceof CreatorProperty)) { cprop = (CreatorProperty) cp; break; } } } if (cprop == null) { throw ctxt.mappingException("Could not find creator property with name '%s' (in class %s)", name, beanDesc.getBeanClass().getName()); } if (prop != null) { cprop.setFallbackSetter(prop); } prop = cprop; builder.addCreatorProperty(cprop); continue; } if (prop != null) { Class<?>[] views = propDef.findViews(); if (views == null) { // one more twist: if default inclusion disabled, need to force empty set of views if (!ctxt.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)) { views = NO_VIEWS; } } // one more thing before adding to builder: copy any metadata prop.setViews(views); builder.addProperty(prop); } } } /** * Helper method called to filter out explicit ignored properties, * as well as properties that have "ignorable types". * Note that this will not remove properties that have no * setters. */ protected List<BeanPropertyDefinition> filterBeanProps(DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder, List<BeanPropertyDefinition> propDefsIn, Set<String> ignored) throws JsonMappingException { ArrayList<BeanPropertyDefinition> result = new ArrayList<BeanPropertyDefinition>( Math.

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> creating new serializers * as need be), * * @param rootType Type to use for locating serializer to use, instead of actual * runtime type. Must be actual type, or one of its super types */ public void serializeValue(JsonGenerator gen, Object value, JavaType rootType) throws IOException { if (value == null) { _serializeNull(gen); return; } // Let's ensure types are compatible at this point if (!rootType.getRawClass().isAssignableFrom(value.getClass())) { _reportIncompatibleRootType(value, rootType); } // root value, not reached via property: JsonSerializer<Object> ser = findTypedValueSerializer(rootType, true, null); // Ok: should we wrap result in an additional property ("root name")? final boolean wrap; PropertyName rootName = _config.getFullRootName(); if (rootName == null) { // not explicitly specified // [JACKSON-163] wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE); if (wrap) { gen.writeStartObject(); PropertyName pname = _config.findRootName(value.getClass()); gen.writeFieldName(pname.simpleAsEncoded(_config)); } } else if (rootName.isEmpty()) { wrap = false; } else { // [JACKSON-764] // empty String means explicitly disabled; non-empty that it is enabled wrap = true; gen.writeStartObject(); gen.writeFieldName(rootName.getSimpleName()); } try { ser.serialize(value, gen, this); if (wrap) { gen.writeEndObject(); } } catch (IOException ioe) { // no wrapping for IO (and derived) throw ioe; } catch (Exception e) { // but others do need to be, to get path etc String msg = e.getMessage(); if (msg == null) { msg = "[no message for "+e.getClass().getName()+"]"; } throw JsonMappingException.from(gen, msg, e); } } /** * The method to be called by {@link ObjectWriter} * for serializing given value (assumed to be of specified root type, * instead of runtime type of value), when it may know specific * {@link JsonSerializer} to use. * * @param rootType Type to use for locating serializer to use, instead of actual * runtime type, if no serializer is passed * @param ser Root Serializer to use, if not null * * @since 2.1 */ public void serializeValue(JsonGenerator gen

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>, Object value, JavaType rootType, JsonSerializer<Object> ser) throws IOException { if (value == null) { _serializeNull(gen); return; } // Let's ensure types are compatible at this point if ((rootType != null) && !rootType.getRawClass().isAssignableFrom(value.getClass())) { _reportIncompatibleRootType(value, rootType); } // root value, not reached via property: if (ser == null) { ser = findTypedValueSerializer(rootType, true, null); } // Ok: should we wrap result in an additional property ("root name")? final boolean wrap; PropertyName rootName = _config.getFullRootName(); if (rootName == null) { // not explicitly specified // [JACKSON-163] wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE); if (wrap) { gen.writeStartObject(); PropertyName pname = (rootType == null) ? _config.findRootName(value.getClass()) : _config.findRootName(rootType); gen.writeFieldName(pname.simpleAsEncoded(_config)); } } else if (rootName.isEmpty()) { wrap = false; } else { // [JACKSON-764] // empty String means explicitly disabled; non-empty that it is enabled wrap = true; gen.writeStartObject(); gen.writeFieldName(rootName.getSimpleName()); } try { ser.serialize(value, gen, this); if (wrap) { gen.writeEndObject(); } } catch (IOException ioe) { // no wrapping for IO (and derived) throw ioe; } catch (Exception e) { // but others do need to be, to get path etc String msg = e.getMessage(); if (msg == null) { msg = "[no message for "+e.getClass().getName()+"]"; } throw JsonMappingException.from(gen, msg, e); } } /** * Alternate serialization call used for polymorphic types, when {@link TypeSerializer} * is already known, but the actual serializer may or may not be. * * @since 2.6 */ public void serializePolymorphic(JsonGenerator gen, Object value, JavaType rootType, JsonSerializer<Object> valueSer, TypeSerializer typeSer) throws IOException { if (value == null) { _serializeNull(gen); return; } // Let's ensure types are compatible at this point if ((rootType != null) && !rootType.getRawClass().isAssignableFrom(value.getClass())) {

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>canUseFor(generatorType)) { generator = gen; break; } } } if (generator == null) { generator = generatorType.newForSerialization(this); _objectIdGenerators.add(generator); } WritableObjectId oid = new WritableObjectId(generator); _seenObjectIds.put(forPojo, oid); return oid; } /** * Overridable helper method used for creating {@link java.util.Map} * used for storing mappings from serializable objects to their * Object Ids. * * @since 2.3 */ protected Map<Object,WritableObjectId> _createObjectIdMap() { /* 06-Aug-2013, tatu: We may actually want to use equality, * instead of identity... so: */ if (isEnabled(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID)) { return new HashMap<Object,WritableObjectId>(); } return new IdentityHashMap<Object,WritableObjectId>(); } /* /********************************************************** /* Factory method impls /********************************************************** */ @Override public JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef) throws JsonMappingException { if (serDef == null) { return null; } JsonSerializer<?> ser; if (serDef instanceof JsonSerializer) { ser = (JsonSerializer<?>) serDef; } else { /* Alas, there's no way to force return type of "either class * X or Y" -- need to throw an exception after the fact */ if (!(serDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned serializer definition of type " +serDef.getClass().getName()+"; expected type JsonSerializer or Class<JsonSerializer> instead"); } Class<?> serClass = (Class<?>)serDef; // there are some known "no class" markers to consider too: if (serClass == JsonSerializer.None.class || ClassUtil.isBogusClass(serClass)) { return null; } if (!JsonSerializer.class.isAssignableFrom(serClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class " +serClass.getName()+"; expected Class<JsonSerializer>"); } HandlerInstantiator hi = _config.getHandlerInstantiator(); ser = (hi == null) ? null : hi.serializerInstance(_config, annotated, serClass); if (ser == null) { ser = (JsonSerializer<?>) ClassUtil.createInstance(serClass, _config.canOverrideAccessModifiers()); } } return (JsonSerializer<Object>) _handleResolvable(ser); } /* /********************************************************

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.deser.std; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.KeyDeserializers; import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.EnumResolver; /** * Helper class used to contain simple/well-known key deserializers. * Following kinds of Objects can be handled currently: *<ul> * <li>Primitive wrappers (Boolean, Byte, Char, Short, Integer, Float, Long, Double)</li> * <li>Enums (usually not needed, since EnumMap doesn't call us)</li> * <li>{@link java.util.Date}</li> * <li>{@link java.util.Calendar}</li> * <li>{@link java.util.UUID}</li> * <li>{@link java.util.Locale}</li> * <li>Anything with constructor that takes a single String arg * (if not explicitly @JsonIgnore'd)</li> * <li>Anything with {@code static T valueOf(String)} factory method * (if not explicitly @JsonIgnore'd)</li> *</ul> */ public class StdKeyDeserializers implements KeyDeserializers, java.io.Serializable { private static final long serialVersionUID = 1L; public static KeyDeserializer constructEnumKeyDeserializer(EnumResolver enumResolver) { return new StdKeyDeserializer.EnumKD(enumResolver, null); } public static KeyDeserializer constructEnumKeyDeserializer(EnumResolver enumResolver, AnnotatedMethod factory) { return new StdKeyDeserializer.EnumKD(enumResolver, factory); } public static KeyDeserializer constructDelegatingKeyDeserializer(DeserializationConfig config, JavaType type, JsonDeserializer<?> deser) { return new StdKeyDeserializer.DelegatingKD(type.getRawClass(), deser); } public static KeyDeserializer findStringBasedKeyDeserializer(DeserializationConfig config, JavaType type) { /* We don't need full deserialization information, just need to * know creators. */ BeanDescription beanDesc = config.introspect(type); // Ok, so: can we find T(String) constructor? Constructor<?> ctor = beanDesc.findSingleArgConstructor(String.class); if (ctor != null) { if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(ctor, config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } return new Std

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>KeyDeserializer.StringCtorKeyDeserializer(ctor); } /* or if not, "static T valueOf(String)" (or equivalent marked * with @JsonCreator annotation?) */ Method m = beanDesc.findFactoryMethod(String.class); if (m != null){ if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(m, config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } return new StdKeyDeserializer.StringFactoryKeyDeserializer(m); } // nope, no such luck... return null; } /* /********************************************************** /* KeyDeserializers implementation /********************************************************** */ @Override public KeyDeserializer findKeyDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { Class<?> raw = type.getRawClass(); // 23-Apr-2013, tatu: Map primitive types, just in case one was given if (raw.isPrimitive()) { raw = ClassUtil.wrapperType(raw); } return StdKeyDeserializer.forType(raw); } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; /** * Standard deserializer for {@link EnumSet}s. * <p> * Note: casting within this class is all messed up -- just could not figure out a way * to properly deal with recursive definition of "EnumSet&lt;K extends Enum&lt;K&gt;, V&gt; */ @SuppressWarnings("rawtypes") public class EnumSetDeserializer extends StdDeserializer<EnumSet<?>> implements ContextualDeserializer { private static final long serialVersionUID = 1L; // since 2.5 protected final JavaType _enumType; protected final Class<Enum> _enumClass; protected JsonDeserializer<Enum<?>> _enumDeserializer; /** * Specific override for this instance (from proper, or global per-type overrides) * to indicate whether single value may be taken to mean an unwrapped one-element array * or not. If null, left to global defaults. * * @since 2.7 */ protected final Boolean _unwrapSingle; /* /********************************************************** /* Life-cycle /********************************************************** */ @SuppressWarnings("unchecked" ) public EnumSetDeserializer(JavaType enumType, JsonDeserializer<?> deser) { super(EnumSet.class); _enumType = enumType; _enumClass = (Class<Enum>) enumType.getRawClass(); // sanity check if (!_enumClass.isEnum()) { throw new IllegalArgumentException("Type "+enumType+" not Java Enum type"); } _enumDeserializer = (JsonDeserializer<Enum<?>>) deser; _unwrapSingle = null; } /** * @since 2.7 */ @SuppressWarnings("unchecked" ) protected EnumSetDeserializer(EnumSetDeserializer base, JsonDeserializer<?> deser, Boolean unwrapSingle) { super(EnumSet.class); _enumType = base._enumType; _enumClass = base._enumClass; _enumDeserializer = (JsonDeserializer<Enum<?>>) deser; _unwrapSingle = unwrapSingle; } public EnumSetDeserializer withDeserializer(JsonDeserializer<?> deser) { if (_enumDeserializer == deser) { return this; } return new EnumSetDeserializer(this, deser, _unwrapSingle); } public EnumSetDeserializer withResolved(JsonDeserializer<?> deser, Boolean unwrapSingle

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>; } /** * Method for getting current {@link SerializerFactoryConfig}. *<p> * Note that since instances are immutable, you can NOT change settings * by accessing an instance and calling methods: this will simply create * new instance of config object. */ public SerializerFactoryConfig getFactoryConfig() { return _factoryConfig; } /** * Method used for creating a new instance of this factory, but with different * configuration. Reason for specifying factory method (instead of plain constructor) * is to allow proper sub-classing of factories. *<p> * Note that custom sub-classes generally <b>must override</b> implementation * of this method, as it usually requires instantiating a new instance of * factory type. Check out javadocs for * {@link com.fasterxml.jackson.databind.ser.BeanSerializerFactory} for more details. */ public abstract SerializerFactory withConfig(SerializerFactoryConfig config); /** * Convenience method for creating a new factory instance with an additional * serializer provider. */ @Override public final SerializerFactory withAdditionalSerializers(Serializers additional) { return withConfig(_factoryConfig.withAdditionalSerializers(additional)); } /** * Convenience method for creating a new factory instance with an additional * key serializer provider. */ @Override public final SerializerFactory withAdditionalKeySerializers(Serializers additional) { return withConfig(_factoryConfig.withAdditionalKeySerializers(additional)); } /** * Convenience method for creating a new factory instance with additional bean * serializer modifier. */ @Override public final SerializerFactory withSerializerModifier(BeanSerializerModifier modifier) { return withConfig(_factoryConfig.withSerializerModifier(modifier)); } /* /********************************************************** /* SerializerFactory impl /********************************************************** */ // Implemented by sub-classes @Override public abstract JsonSerializer<Object> createSerializer(SerializerProvider prov, JavaType type) throws JsonMappingException; @Override @SuppressWarnings("unchecked") public JsonSerializer<Object> createKeySerializer(SerializationConfig config, JavaType keyType, JsonSerializer<Object> defaultImpl) { // We should not need any member method info; at most class annotations for Map type // ... at least, not here. BeanDescription beanDesc = config.introspectClassAnnotations(keyType.getRawClass()); JsonSerializer<?> ser = null; // Minor optimization: to avoid constructing beanDesc, bail out if none registered if (_factoryConfig.hasKeySerializers()) { // Only thing we have here are module-provided key serializers: for (Serializers serializers : _factoryConfig.keySerializers()) { ser = serializers.findSerializer(config, keyType, bean

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Desc); if (ser != null) { break; } } } if (ser == null) { ser = defaultImpl; if (ser == null) { ser = StdKeySerializers.getStdKeySerializer(config, keyType.getRawClass(), false); // As per [databind#47], also need to support @JsonValue if (ser == null) { beanDesc = config.introspect(keyType); AnnotatedMethod am = beanDesc.findJsonValueMethod(); if (am != null) { final Class<?> rawType = am.getRawReturnType(); JsonSerializer<?> delegate = StdKeySerializers.getStdKeySerializer(config, rawType, true); Method m = am.getAnnotated(); if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(m, config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } ser = new JsonValueSerializer(m, delegate); } else { ser = StdKeySerializers.getFallbackKeySerializer(config, keyType.getRawClass()); } } } } // [databind#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifyKeySerializer(config, keyType, beanDesc, ser); } } return (JsonSerializer<Object>) ser; } /** * Method called to construct a type serializer for values with given declared * base type. This is called for values other than those of bean property * types. */ @Override public TypeSerializer createTypeSerializer(SerializationConfig config, JavaType baseType) { BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass()); AnnotatedClass ac = bean.getClassInfo(); AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType); /* Ok: if there is no explicit type info handler, we may want to * use a default. If so, config object knows what to use. */ Collection<NamedType> subtypes = null; if (b == null) { b = config.getDefaultTyper(baseType); } else { subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, ac); } if (b == null) { return null; } // 10-Jun-2015, tatu: Since not created for Bean Property, no need for post-processing // wrt EXTERNAL_PROPERTY return

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> b.buildTypeSerializer(config, baseType, subtypes); } /* /********************************************************** /* Additional API for other core classes /********************************************************** */ protected abstract Iterable<Serializers> customSerializers(); /* /********************************************************** /* Overridable secondary serializer accessor methods /********************************************************** */ /** * Method that will use fast lookup (and identity comparison) methods to * see if we know serializer to use for given type. */ protected final JsonSerializer<?> findSerializerByLookup(JavaType type, SerializationConfig config, BeanDescription beanDesc, boolean staticTyping) { Class<?> raw = type.getRawClass(); String clsName = raw.getName(); JsonSerializer<?> ser = _concrete.get(clsName); if (ser == null) { Class<? extends JsonSerializer<?>> serClass = _concreteLazy.get(clsName); if (serClass != null) { try { return serClass.newInstance(); } catch (Exception e) { throw new IllegalStateException("Failed to instantiate standard serializer (of type "+serClass.getName()+"): " +e.getMessage(), e); } } } return ser; } /** * Method called to see if one of primary per-class annotations * (or related, like implementing of {@link JsonSerializable}) * determines the serializer to use. *<p> * Currently handles things like: *<ul> * <li>If type implements {@link JsonSerializable}, use that * </li> * <li>If type has {@link com.fasterxml.jackson.annotation.JsonValue} annotation (or equivalent), build serializer * based on that property * </li> *</ul> * * @since 2.0 */ protected final JsonSerializer<?> findSerializerByAnnotations(SerializerProvider prov, JavaType type, BeanDescription beanDesc) throws JsonMappingException { Class<?> raw = type.getRawClass(); // First: JsonSerializable? if (JsonSerializable.class.isAssignableFrom(raw)) { return SerializableSerializer.instance; } // Second: @JsonValue for any type AnnotatedMethod valueMethod = beanDesc.findJsonValueMethod(); if (valueMethod != null) { Method m = valueMethod.getAnnotated(); if (prov.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(m, prov.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } JsonSerializer<Object> ser = findSerializerFromAnnotation(prov, valueMethod); return new JsonValueSerializer(m, ser); } // No well-known annotations... return null; } /** * Method for checking if we can determine

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> serializer to use based on set of * known primary types, checking for set of known base types (exact matches * having been compared against with <code>findSerializerByLookup</code>). * This does not include "secondary" interfaces, but * mostly concrete or abstract base classes. */ protected final JsonSerializer<?> findSerializerByPrimaryType(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { Class<?> raw = type.getRawClass(); // Then check for optional/external serializers JsonSerializer<?> ser = findOptionalStdSerializer(prov, type, beanDesc, staticTyping); if (ser != null) { return ser; } if (Calendar.class.isAssignableFrom(raw)) { return CalendarSerializer.instance; } if (java.util.Date.class.isAssignableFrom(raw)) { return DateSerializer.instance; } if (Map.Entry.class.isAssignableFrom(raw)) { // 18-Oct-2015, tatu: With 2.7, need to dig type info: JavaType mapEntryType = type.findSuperType(Map.Entry.class); // 28-Apr-2015, tatu: TypeFactory does it all for us already so JavaType kt = mapEntryType.containedType(0); if (kt == null) { kt = TypeFactory.unknownType(); } JavaType vt = mapEntryType.containedType(1); if (vt == null) { vt = TypeFactory.unknownType(); } return buildMapEntrySerializer(prov.getConfig(), type, beanDesc, staticTyping, kt, vt); } if (ByteBuffer.class.isAssignableFrom(raw)) { return new ByteBufferSerializer(); } if (InetAddress.class.isAssignableFrom(raw)) { return new InetAddressSerializer(); } if (InetSocketAddress.class.isAssignableFrom(raw)) { return new InetSocketAddressSerializer(); } if (TimeZone.class.isAssignableFrom(raw)) { return new TimeZoneSerializer(); } if (java.nio.charset.Charset.class.isAssignableFrom(raw)) { return ToStringSerializer.instance; } if (Number.class.isAssignableFrom(raw)) { // 21-May-2014, tatu: Couple of alternatives actually JsonFormat.Value format = beanDesc.findExpectedFormat(null); if (format != null) { switch (format.getShape()) { case STRING: return ToStringSerializer.instance; case OBJECT: // need to bail out to let it be serialized as POJO case ARRAY: // or, I guess ARRAY; otherwise no point in spec

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>ulating return null; default: } } return NumberSerializer.instance; } if (Enum.class.isAssignableFrom(raw)) { return buildEnumSerializer(prov.getConfig(), type, beanDesc); } return null; } /** * Overridable method called after checking all other types. * * @since 2.2 */ protected JsonSerializer<?> findOptionalStdSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { return OptionalHandlerFactory.instance.findSerializer(prov.getConfig(), type, beanDesc); } /** * Reflection-based serialized find method, which checks if * given class implements one of recognized "add-on" interfaces. * Add-on here means a role that is usually or can be a secondary * trait: for example, * bean classes may implement {@link Iterable}, but their main * function is usually something else. The reason for */ protected final JsonSerializer<?> findSerializerByAddonType(SerializationConfig config, JavaType javaType, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { Class<?> rawType = javaType.getRawClass(); if (Iterator.class.isAssignableFrom(rawType)) { JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterator.class); JavaType vt = (params == null || params.length != 1) ? TypeFactory.unknownType() : params[0]; return buildIteratorSerializer(config, javaType, beanDesc, staticTyping, vt); } if (Iterable.class.isAssignableFrom(rawType)) { JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterable.class); JavaType vt = (params == null || params.length != 1) ? TypeFactory.unknownType() : params[0]; return buildIterableSerializer(config, javaType, beanDesc, staticTyping, vt); } if (CharSequence.class.isAssignableFrom(rawType)) { return ToStringSerializer.instance; } return null; } /** * Helper method called to check if a class or method * has an annotation * (@link com.fasterxml.jackson.databind.annotation.JsonSerialize#using) * that tells the class to use for serialization. * Returns null if no such annotation found. */ @SuppressWarnings("unchecked") protected JsonSerializer<Object> findSerializerFromAnnotation(SerializerProvider prov, Annotated a) throws JsonMappingException { Object serDef = prov.getAnnotationIntrospector().findSerializer(a); if (serDef == null) { return null; } JsonSerializer<Object>

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> ser = prov.serializerInstance(a, serDef); // One more thing however: may need to also apply a converter: return (JsonSerializer<Object>) findConvertingSerializer(prov, a, ser); } /** * Helper method that will check whether given annotated entity (usually class, * but may also be a property accessor) indicates that a {@link Converter} is to * be used; and if so, to construct and return suitable serializer for it. * If not, will simply return given serializer as is. */ protected JsonSerializer<?> findConvertingSerializer(SerializerProvider prov, Annotated a, JsonSerializer<?> ser) throws JsonMappingException { Converter<Object,Object> conv = findConverter(prov, a); if (conv == null) { return ser; } JavaType delegateType = conv.getOutputType(prov.getTypeFactory()); return new StdDelegatingSerializer(conv, delegateType, ser); } protected Converter<Object,Object> findConverter(SerializerProvider prov, Annotated a) throws JsonMappingException { Object convDef = prov.getAnnotationIntrospector().findSerializationConverter(a); if (convDef == null) { return null; } return prov.converterInstance(a, convDef); } /* /********************************************************** /* Factory methods, container types: /********************************************************** */ /** * @since 2.1 */ protected JsonSerializer<?> buildContainerSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { final SerializationConfig config = prov.getConfig(); /* [databind#23], 15-Mar-2013, tatu: must force static handling of root value type, * with just one important exception: if value type is "untyped", let's * leave it as is; no clean way to make it work. */ if (!staticTyping && type.useStaticType()) { if (!type.isContainerType() || type.getContentType().getRawClass() != Object.class) { staticTyping = true; } } // Let's see what we can learn about element/content/value type, type serializer for it: JavaType elementType = type.getContentType(); TypeSerializer elementTypeSerializer = createTypeSerializer(config, elementType); // if elements have type serializer, can not force static typing: if (elementTypeSerializer != null) { staticTyping = false; } JsonSerializer<Object> elementValueSerializer = _findContentSerializer(prov, beanDesc.getClassInfo()); if (type.isMapLikeType()) { // implements java.util.Map MapLikeType

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>factoryConfig.serializerModifiers()) { ser = mod.modifyCollectionLikeSerializer(config, clType, beanDesc, ser); } } } return ser; } if (type.isArrayType()) { return buildArraySerializer(prov, (ArrayType) type, beanDesc, staticTyping, elementTypeSerializer, elementValueSerializer); } return null; } /** * Helper method that handles configuration details when constructing serializers for * {@link java.util.List} types that support efficient by-index access * * @since 2.1 */ protected JsonSerializer<?> buildCollectionSerializer(SerializerProvider prov, CollectionType type, BeanDescription beanDesc, boolean staticTyping, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) throws JsonMappingException { SerializationConfig config = prov.getConfig(); JsonSerializer<?> ser = null; // Order of lookups: // 1. Custom serializers // 2. Annotations (@JsonValue, @JsonDeserialize) // 3. Defaults for (Serializers serializers : customSerializers()) { // (1) Custom ser = serializers.findCollectionSerializer(config, type, beanDesc, elementTypeSerializer, elementValueSerializer); if (ser != null) { break; } } if (ser == null) { ser = findSerializerByAnnotations(prov, type, beanDesc); // (2) Annotations if (ser == null) { // We may also want to use serialize Collections "as beans", if (and only if) // this is specified with `@JsonFormat(shape=Object)` JsonFormat.Value format = beanDesc.findExpectedFormat(null); if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) { return null; } Class<?> raw = type.getRawClass(); if (EnumSet.class.isAssignableFrom(raw)) { // this may or may not be available (Class doesn't; type of field/method does) JavaType enumType = type.getContentType(); // and even if nominally there is something, only use if it really is enum if (!enumType.isEnumType()) { enumType = null; } ser = buildEnumSetSerializer(enumType); } else { Class<?> elementRaw = type.getContentType().getRawClass(); if (isIndexedList(raw)) { if (elementRaw == String.class) { // [JACKSON-829] Must NOT use if we have custom serializer if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) { ser = IndexedStringListSerializer.instance; } } else

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> { ser = buildIndexedListSerializer(type.getContentType(), staticTyping, elementTypeSerializer, elementValueSerializer); } } else if (elementRaw == String.class) { // [JACKSON-829] Must NOT use if we have custom serializer if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) { ser = StringCollectionSerializer.instance; } } if (ser == null) { ser = buildCollectionSerializer(type.getContentType(), staticTyping, elementTypeSerializer, elementValueSerializer); } } } } // [databind#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifyCollectionSerializer(config, type, beanDesc, ser); } } return ser; } /* /********************************************************** /* Factory methods, for Collections /********************************************************** */ protected boolean isIndexedList(Class<?> cls) { return RandomAccess.class.isAssignableFrom(cls); } public ContainerSerializer<?> buildIndexedListSerializer(JavaType elemType, boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) { return new IndexedListSerializer(elemType, staticTyping, vts, valueSerializer); } public ContainerSerializer<?> buildCollectionSerializer(JavaType elemType, boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) { return new CollectionSerializer(elemType, staticTyping, vts, valueSerializer); } public JsonSerializer<?> buildEnumSetSerializer(JavaType enumType) { return new EnumSetSerializer(enumType); } /* /********************************************************** /* Factory methods, for Maps /********************************************************** */ /** * Helper method that handles configuration details when constructing serializers for * {@link java.util.Map} types. */ protected JsonSerializer<?> buildMapSerializer(SerializerProvider prov, MapType type, BeanDescription beanDesc, boolean staticTyping, JsonSerializer<Object> keySerializer, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) throws JsonMappingException { final SerializationConfig config = prov.getConfig(); JsonSerializer<?> ser = null; // Order of lookups: // 1. Custom serializers // 2. Annotations (@JsonValue, @JsonDeserialize) // 3. Defaults for (Serializers serializers : customSerializers()) { // (1) Custom ser = serializers.findMapSerializer(config, type, beanDesc, keySerializer, elementTypeSerializer, elementValueSerializer); if (ser != null) { break; } } if (

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> /** * Helper method that handles configuration details when constructing serializers for * <code>Object[]</code> (and subtypes, except for String). */ protected JsonSerializer<?> buildArraySerializer(SerializerProvider prov, ArrayType type, BeanDescription beanDesc, boolean staticTyping, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) throws JsonMappingException { // 25-Jun-2015, tatu: Note that unlike with Collection(Like) and Map(Like) types, array // types can not be annotated (in theory I guess we could have mix-ins but... ?) // so we need not do primary annotation lookup here. // So all we need is (1) Custom, (2) Default array serializers SerializationConfig config = prov.getConfig(); JsonSerializer<?> ser = null; for (Serializers serializers : customSerializers()) { // (1) Custom ser = serializers.findArraySerializer(config, type, beanDesc, elementTypeSerializer, elementValueSerializer); if (ser != null) { break; } } if (ser == null) { Class<?> raw = type.getRawClass(); // Important: do NOT use standard serializers if non-standard element value serializer specified if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) { if (String[].class == raw) { ser = StringArraySerializer.instance; } else { // other standard types? ser = StdArraySerializers.findStandardImpl(raw); } } if (ser == null) { ser = new ObjectArraySerializer(type.getContentType(), staticTyping, elementTypeSerializer, elementValueSerializer); } } // [databind#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifyArraySerializer(config, type, beanDesc, ser); } } return ser; } /* /********************************************************** /* Factory methods, for non-container types /********************************************************** */ /** * @since 2.5 */ protected JsonSerializer<?> buildIteratorSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc, boolean staticTyping, JavaType valueType) throws JsonMappingException { return new IteratorSerializer(valueType, staticTyping, createTypeSerializer(config, valueType)); } @Deprecated // since 2.5 protected JsonSerializer<?> buildIteratorSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { JavaType[] params = config

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>.getTypeFactory().findTypeParameters(type, Iterator.class); JavaType vt = (params == null || params.length != 1) ? TypeFactory.unknownType() : params[0]; return buildIteratorSerializer(config, type, beanDesc, staticTyping, vt); } /** * @since 2.5 */ protected JsonSerializer<?> buildIterableSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc, boolean staticTyping, JavaType valueType) throws JsonMappingException { return new IterableSerializer(valueType, staticTyping, createTypeSerializer(config, valueType)); } @Deprecated // since 2.5 protected JsonSerializer<?> buildIterableSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { JavaType[] params = config.getTypeFactory().findTypeParameters(type, Iterable.class); JavaType vt = (params == null || params.length != 1) ? TypeFactory.unknownType() : params[0]; return buildIterableSerializer(config, type, beanDesc, staticTyping, vt); } /** * @since 2.5 */ protected JsonSerializer<?> buildMapEntrySerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc, boolean staticTyping, JavaType keyType, JavaType valueType) throws JsonMappingException { return new MapEntrySerializer(valueType, keyType, valueType, staticTyping, createTypeSerializer(config, valueType), null); } protected JsonSerializer<?> buildEnumSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) throws JsonMappingException { /* As per [databind#24], may want to use alternate shape, serialize as JSON Object. * Challenge here is that EnumSerializer does not know how to produce * POJO style serialization, so we must handle that special case separately; * otherwise pass it to EnumSerializer. */ JsonFormat.Value format = beanDesc.findExpectedFormat(null); if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) { // one special case: suppress serialization of "getDeclaringClass()"... ((BasicBeanDescription) beanDesc).removeProperty("declaringClass"); // returning null will mean that eventually BeanSerializer gets constructed return null; } @SuppressWarnings("unchecked") Class<Enum<?>> enumClass = (Class<Enum<?>>) type.getRawClass(); JsonSerializer<?> ser = EnumSerializer.construct(enumClass, config, beanDesc, format); // [Issue#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factory

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> /* Need to resolve? Mostly done for bean deserializers; required for * resolving cyclic references. */ if (isResolvable) { _incompleteDeserializers.put(type, deser); ((ResolvableDeserializer)deser).resolve(ctxt); _incompleteDeserializers.remove(type); } if (addToCache) { _cachedDeserializers.put(type, deser); } return deser; } /* /********************************************************** /* Helper methods for actual construction of deserializers /********************************************************** */ /** * Method that does the heavy lifting of checking for per-type annotations, * find out full type, and figure out which actual factory method * to call. */ @SuppressWarnings("unchecked") protected JsonDeserializer<Object> _createDeserializer(DeserializationContext ctxt, DeserializerFactory factory, JavaType type) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); // First things first: do we need to use abstract type mapping? if (type.isAbstract() || type.isMapLikeType() || type.isCollectionLikeType()) { type = factory.mapAbstractType(config, type); } BeanDescription beanDesc = config.introspect(type); // Then: does type define explicit deserializer to use, with annotation(s)? JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo()); if (deser != null) { return deser; } // If not, may have further type-modification annotations to check: JavaType newType = modifyTypeByAnnotation(ctxt, beanDesc.getClassInfo(), type); if (newType != type) { type = newType; beanDesc = config.introspect(newType); } // We may also have a Builder type to consider... Class<?> builder = beanDesc.findPOJOBuilder(); if (builder != null) { return (JsonDeserializer<Object>) factory.createBuilderBasedDeserializer( ctxt, type, beanDesc, builder); } // Or perhaps a Converter? Converter<Object,Object> conv = beanDesc.findDeserializationConverter(); if (conv == null) { // nope, just construct in normal way return (JsonDeserializer<Object>) _createDeserializer2(ctxt, factory, type, beanDesc); } // otherwise need to do bit of introspection JavaType delegateType = conv.getInputType(ctxt.getTypeFactory()); // One more twist, as per [Issue#288]; probably need to get new BeanDesc if (!delegateType.hasRawClass(type.getRawClass())) { beanDesc = config.introspect(delegate

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Type); } return new StdDelegatingDeserializer<Object>(conv, delegateType, _createDeserializer2(ctxt, factory, delegateType, beanDesc)); } protected JsonDeserializer<?> _createDeserializer2(DeserializationContext ctxt, DeserializerFactory factory, JavaType type, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); // If not, let's see which factory method to use: if (type.isEnumType()) { return factory.createEnumDeserializer(ctxt, type, beanDesc); } if (type.isContainerType()) { if (type.isArrayType()) { return factory.createArrayDeserializer(ctxt, (ArrayType) type, beanDesc); } if (type.isMapLikeType()) { MapLikeType mlt = (MapLikeType) type; if (mlt.isTrueMapType()) { return factory.createMapDeserializer(ctxt,(MapType) mlt, beanDesc); } return factory.createMapLikeDeserializer(ctxt, mlt, beanDesc); } if (type.isCollectionLikeType()) { /* 03-Aug-2012, tatu: As per [Issue#40], one exception is if shape * is to be Shape.OBJECT. Ideally we'd determine it bit later on * (to allow custom handler checks), but that won't work for other * reasons. So do it here. */ JsonFormat.Value format = beanDesc.findExpectedFormat(null); if (format == null || format.getShape() != JsonFormat.Shape.OBJECT) { CollectionLikeType clt = (CollectionLikeType) type; if (clt.isTrueCollectionType()) { return factory.createCollectionDeserializer(ctxt, (CollectionType) clt, beanDesc); } return factory.createCollectionLikeDeserializer(ctxt, clt, beanDesc); } } } if (type.isReferenceType()) { return factory.createReferenceDeserializer(ctxt, (ReferenceType) type, beanDesc); } if (JsonNode.class.isAssignableFrom(type.getRawClass())) { return factory.createTreeDeserializer(config, type, beanDesc); } return factory.createBeanDeserializer(ctxt, type, beanDesc); } /** * Helper method called to check if a class or method * has annotation that tells which class to use for deserialization. * Returns null if no such annotation found. */ protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt, Annotated ann) throws JsonMappingException { Object deserDef = ctxt.getAnnotationIntrospector().findDeserializer(ann

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> JsonSerializer or Class<JsonSerializer> instead"); } Class<?> cls = (Class<?>) src; if (cls == noneClass || ClassUtil.isBogusClass(cls)) { return null; } return cls; } /* /********************************************************** /* Overridable error reporting methods /********************************************************** */ // NOTE: changed 2.6 -> 2.7 to pass context; no way to make backwards compatible protected JsonDeserializer<Object> _handleUnknownValueDeserializer(DeserializationContext ctxt, JavaType type) throws JsonMappingException { /* Let's try to figure out the reason, to give better error * messages */ Class<?> rawClass = type.getRawClass(); if (!ClassUtil.isConcrete(rawClass)) { throw JsonMappingException.from(ctxt, "Can not find a Value deserializer for abstract type "+type); } throw JsonMappingException.from(ctxt, "Can not find a Value deserializer for type "+type); } protected KeyDeserializer _handleUnknownKeyDeserializer(DeserializationContext ctxt, JavaType type) throws JsonMappingException { throw JsonMappingException.from(ctxt, "Can not find a (Map) Key deserializer for type "+type); } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>(); MapSerializer ser = new MapSerializer(this, property, keySerializer, valueSerializer, ignored); if (sortKeys != ser._sortKeys) { ser = new MapSerializer(ser, _filterId, sortKeys); } return ser; } @Override public MapSerializer withFilterId(Object filterId) { if (_filterId == filterId) { return this; } _ensureOverride(); return new MapSerializer(this, filterId, _sortKeys); } /** * Mutant factory for constructing an instance with different inclusion strategy * for content (Map values). * * @since 2.5 */ public MapSerializer withContentInclusion(Object suppressableValue) { if (suppressableValue == _suppressableValue) { return this; } _ensureOverride(); return new MapSerializer(this, _valueTypeSerializer, suppressableValue); } /** * @since 2.3 */ public static MapSerializer construct(String[] ignoredList, JavaType mapType, boolean staticValueType, TypeSerializer vts, JsonSerializer<Object> keySerializer, JsonSerializer<Object> valueSerializer, Object filterId) { HashSet<String> ignoredEntries = (ignoredList == null || ignoredList.length == 0) ? null : ArrayBuilders.arrayToSet(ignoredList); JavaType keyType, valueType; if (mapType == null) { keyType = valueType = UNSPECIFIED_TYPE; } else { keyType = mapType.getKeyType(); valueType = mapType.getContentType(); } // If value type is final, it's same as forcing static value typing: if (!staticValueType) { staticValueType = (valueType != null && valueType.isFinal()); } else { // also: Object.class can not be handled as static, ever if (valueType.getRawClass() == Object.class) { staticValueType = false; } } MapSerializer ser = new MapSerializer(ignoredEntries, keyType, valueType, staticValueType, vts, keySerializer, valueSerializer); if (filterId != null) { ser = ser.withFilterId(filterId); } return ser; } /* /********************************************************** /* Post-processing (contextualization) /********************************************************** */ @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { /* 29-Sep-2012, tatu: Actually, we need to do much more contextual * checking here since we finally know for sure the property, * and it may have

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>(cc); if (serializer == null) { if (_valueType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_valueType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicValueSerializers; } } try { serializer.serialize(valueElem, gen, provider); } catch (Exception e) { // Add reference information String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } /** * Serialization method called when exclusion filtering needs to be applied. */ public void serializeOptionalFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider, Object suppressableValue) throws IOException { // If value type needs polymorphic type handling, some more work needed: if (_valueTypeSerializer != null) { serializeTypedFields(value, gen, provider, suppressableValue); return; } final HashSet<String> ignored = _ignoredEntries; PropertySerializerMap serializers = _dynamicValueSerializers; for (Map.Entry<?,?> entry : value.entrySet()) { // First find key serializer final Object keyElem = entry.getKey(); JsonSerializer<Object> keySerializer; if (keyElem == null) { keySerializer = provider.findNullKeySerializer(_keyType, _property); } else { if (ignored != null && ignored.contains(keyElem)) continue; keySerializer = _keySerializer; } // Then value serializer final Object valueElem = entry.getValue(); JsonSerializer<Object> valueSer; if (valueElem == null) { if (suppressableValue != null) { // all suppressions include null-suppression continue; } valueSer = provider.getDefaultNullValueSerializer(); } else { valueSer = _valueSerializer; if (valueSer == null) { Class<?> cc = valueElem.getClass(); valueSer = serializers.serializerFor(cc); if (valueSer == null) { if (_valueType.hasGenericTypes()) { valueSer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_valueType, cc), provider); } else { valueSer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicValueSerializers; } } // also may need to skip non-empty values: if ((suppressableValue == JsonInclude.Include.NON_EMPTY) && valueSer.isEmpty(provider, valueElem)) { continue; } } // and then serialize, if all went well

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Serializer; } // or by value; nulls often suppressed final Object valueElem = entry.getValue(); JsonSerializer<Object> valueSer; // And then value if (valueElem == null) { if (suppressableValue != null) { // all suppressions include null-suppression continue; } valueSer = provider.getDefaultNullValueSerializer(); } else { valueSer = _valueSerializer; if (valueSer == null) { Class<?> cc = valueElem.getClass(); valueSer = serializers.serializerFor(cc); if (valueSer == null) { if (_valueType.hasGenericTypes()) { valueSer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_valueType, cc), provider); } else { valueSer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicValueSerializers; } } // also may need to skip non-empty values: if ((suppressableValue == JsonInclude.Include.NON_EMPTY) && valueSer.isEmpty(provider, valueElem)) { continue; } } // and with that, ask filter to handle it prop.reset(keyElem, keySerializer, valueSer); try { filter.serializeAsField(valueElem, gen, provider, prop); } catch (Exception e) { String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } @Deprecated // since 2.5 public void serializeFilteredFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider, PropertyFilter filter) throws IOException { serializeFilteredFields(value, gen, provider, filter, provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES) ? null : JsonInclude.Include.NON_NULL); } /** * @since 2.5 */ public void serializeTypedFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider, Object suppressableValue) // since 2.5 throws IOException { final HashSet<String> ignored = _ignoredEntries; PropertySerializerMap serializers = _dynamicValueSerializers; for (Map.Entry<?,?> entry : value.entrySet()) { Object keyElem = entry.getKey(); JsonSerializer<Object> keySerializer; if (keyElem == null) { keySerializer = provider.findNullKeySerializer(_keyType, _property); } else { // One twist: is entry ignorable? If so, skip if (ignored != null && ignored.contains(keyElem)) continue; keySerializer = _keySerializer; } final Object valueElem = entry.getValue

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>(); // And then value JsonSerializer<Object> valueSer; if (valueElem == null) { if (suppressableValue != null) { // all suppression include null suppression continue; } valueSer = provider.getDefaultNullValueSerializer(); } else { valueSer = _valueSerializer; Class<?> cc = valueElem.getClass(); valueSer = serializers.serializerFor(cc); if (valueSer == null) { if (_valueType.hasGenericTypes()) { valueSer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_valueType, cc), provider); } else { valueSer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicValueSerializers; } // also may need to skip non-empty values: if ((suppressableValue == JsonInclude.Include.NON_EMPTY) && valueSer.isEmpty(provider, valueElem)) { continue; } } keySerializer.serialize(keyElem, gen, provider); try { valueSer.serializeWithType(valueElem, gen, provider, _valueTypeSerializer); } catch (Exception e) { String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } @Deprecated // since 2.5 protected void serializeTypedFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider) throws IOException { serializeTypedFields(value, gen, provider, provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES) ? null : JsonInclude.Include.NON_NULL); } /* /********************************************************** /* Schema related functionality /********************************************************** */ @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("object", true); //(ryan) even though it's possible to statically determine the "value" type of the map, // there's no way to statically determine the keys, so the "Entries" can't be determined. return o; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonMapFormatVisitor v2 = (visitor == null) ? null : visitor.expectMapFormat(typeHint); if (v2 != null) { v2.keyFormat(_keySerializer, _keyType); JsonSerializer<?> valueSer = _valueSerializer; if (valueSer == null) { valueSer = _findAndAddDynamic(_dynamicValueSerializers, _valueType, visitor.getProvider()); } v2.valueFormat(valueSer, _valueType);

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.JsonParser.NumberType; import com.fasterxml.jackson.core.io.NumberInput; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.Converter; /** * Base class for common deserializers. Contains shared * base functionality for dealing with primitive values, such * as (re)parsing from String. */ public abstract class StdDeserializer<T> extends JsonDeserializer<T> implements java.io.Serializable { private static final long serialVersionUID = 1L; /** * Bitmask that covers {@link DeserializationFeature#USE_BIG_INTEGER_FOR_INTS} * and {@link DeserializationFeature#USE_LONG_FOR_INTS}, used for more efficient * cheks when coercing integral values for untyped deserialization. * * @since 2.6 */ protected final static int F_MASK_INT_COERCIONS = DeserializationFeature.USE_BIG_INTEGER_FOR_INTS.getMask() | DeserializationFeature.USE_LONG_FOR_INTS.getMask(); /** * Type of values this deserializer handles: sometimes * exact types, other time most specific supertype of * types deserializer handles (which may be as generic * as {@link Object} in some case) */ final protected Class<?> _valueClass; protected StdDeserializer(Class<?> vc) { _valueClass = vc; } protected StdDeserializer(JavaType valueType) { _valueClass = (valueType == null) ? null : valueType.getRawClass(); } /** * Copy-constructor for sub-classes to use, most often when creating * new instances for {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer}. * * @since 2.5 */ protected StdDeserializer(StdDeserializer<?> src) { _valueClass = src._valueClass; } /* /********************************************************** /* Accessors /********************************************************** */ @Override public Class<?> handledType() { return _valueClass; } /* /********************************************************** /* Extended API

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>.getCurrentToken(); if (t == JsonToken.END_ARRAY) { break; } // Ok: no need to convert Strings, but must recognize nulls value = (t == JsonToken.VALUE_NULL) ? deser.getNullValue(ctxt) : deser.deserialize(p, ctxt); } else { value = deser.deserialize(p, ctxt); } result.add(value); } return result; } @Override public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException { // In future could check current token... for now this should be enough: return typeDeserializer.deserializeTypedFromArray(p, ctxt); } /** * Helper method called when current token is not START_ARRAY. Will either * throw an exception, or try to handle value as if member of implicit * array, depending on configuration. */ private final Collection<String> handleNonArray(JsonParser p, DeserializationContext ctxt, Collection<String> result) throws IOException { // implicit arrays from single values? boolean canWrap = (_unwrapSingle == Boolean.TRUE) || ((_unwrapSingle == null) && ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)); if (!canWrap) { throw ctxt.mappingException(_collectionType.getRawClass()); } // Strings are one of "native" (intrinsic) types, so there's never type deserializer involved JsonDeserializer<String> valueDes = _valueDeserializer; JsonToken t = p.getCurrentToken(); String value; if (t == JsonToken.VALUE_NULL) { value = (valueDes == null) ? null : valueDes.getNullValue(ctxt); } else { value = (valueDes == null) ? _parseString(p, ctxt) : valueDes.deserialize(p, ctxt); } result.add(value); return result; } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> a "real" * Collection type; meaning whether it represents a parameterized subtype of * {@link java.util.Collection} or just something that acts like one. */ public boolean isTrueMapType() { return Map.class.isAssignableFrom(_class); } /* * /********************************************************** /* Standard * methods /********************************************************** */ @Override public String toString() { return "[map-like type; class " + _class.getName() + ", " + _keyType + " -> " + _valueType + "]"; } @Override public boolean equals(Object o) { if (o == this) return true; if (o == null) return false; if (o.getClass() != getClass()) return false; MapLikeType other = (MapLikeType) o; return (_class == other._class) && _keyType.equals(other._keyType) && _valueType.equals(other._valueType); } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.type; import java.lang.reflect.Array; import com.fasterxml.jackson.databind.JavaType; /** * Array types represent Java arrays, both primitive and object valued. * Further, Object-valued arrays can have element type of any other * legal {@link JavaType}. */ public final class ArrayType extends TypeBase { private static final long serialVersionUID = 1L; /** * Type of elements in the array. */ protected final JavaType _componentType; /** * We will also keep track of shareable instance of empty array, * since it usually needs to be constructed any way; and because * it is essentially immutable and thus can be shared. */ protected final Object _emptyArray; protected ArrayType(JavaType componentType, TypeBindings bindings, Object emptyInstance, Object valueHandler, Object typeHandler, boolean asStatic) { // No super-class, interfaces, for now super(emptyInstance.getClass(), bindings, null, null, componentType.hashCode(), valueHandler, typeHandler, asStatic); _componentType = componentType; _emptyArray = emptyInstance; } public static ArrayType construct(JavaType componentType, TypeBindings bindings) { return construct(componentType, bindings, null, null); } public static ArrayType construct(JavaType componentType, TypeBindings bindings, Object valueHandler, Object typeHandler) { // Figuring out raw class for generic array is actually bit tricky... Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0); return new ArrayType(componentType, bindings, emptyInstance, valueHandler, typeHandler, false); } @Override public JavaType withContentType(JavaType contentType) { Object emptyInstance = Array.newInstance(contentType.getRawClass(), 0); return new ArrayType(contentType, _bindings, emptyInstance, _valueHandler, _typeHandler, _asStatic); } @Override public ArrayType withTypeHandler(Object h) { if (h == _typeHandler) { return this; } return new ArrayType(_componentType, _bindings, _emptyArray, _valueHandler, h, _asStatic); } @Override public ArrayType withContentTypeHandler(Object h) { if (h == _componentType.<Object>getTypeHandler()) { return this; } return new ArrayType(_componentType.withTypeHandler(h), _bindings, _emptyArray, _valueHandler, _typeHandler, _asStatic); } @Override public ArrayType withValueHandler(Object h) { if (h == _

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>" aka runtime typing): * meaning that no runtime information is needed for determining serializers to use. * The main use case is to allow forcing of specific root value serialization type, * and specifically in resolving serializers for contained types (element types * for arrays, Collections and Maps). * * @since 2.2 */ public abstract JavaType withStaticTyping(); /* /********************************************************** /* Type coercion fluent factory methods /********************************************************** */ /** * Mutant factory method that will try to create and return a sub-type instance * for known parameterized types; for other types will return `null` to indicate * that no just refinement makes necessary sense, without trying to detect * special status through implemented interfaces. * * @since 2.7 */ public abstract JavaType refine(Class<?> rawType, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces); /** * Legacy method used for forcing sub-typing of this type into * type specified by specific type erasure. * Deprecated as of 2.7 as such specializations really ought to * go through {@link TypeFactory}, not directly via {@link JavaType}. * * @since 2.7 */ @Deprecated public JavaType forcedNarrowBy(Class<?> subclass) { if (subclass == _class) { // can still optimize for simple case return this; } JavaType result = _narrow(subclass); // TODO: these checks should NOT actually be needed; above should suffice: if (_valueHandler != result.<Object>getValueHandler()) { result = result.withValueHandler(_valueHandler); } if (_typeHandler != result.<Object>getTypeHandler()) { result = result.withTypeHandler(_typeHandler); } return result; } @Deprecated // since 2.7 protected abstract JavaType _narrow(Class<?> subclass); /* /********************************************************** /* Implementation of ResolvedType API /********************************************************** */ @Override public final Class<?> getRawClass() { return _class; } /** * Method that can be used to check whether this type has * specified Class as its type erasure. Put another way, returns * true if instantiation of this Type is given (type-erased) Class. */ @Override public final boolean hasRawClass(Class<?> clz) { return _class == clz; } /** * @since 2.6 */ public final boolean isTypeOrSubTypeOf(Class<?> clz) { return (_class == clz) || (clz.isAssignableFrom(_class)); } @Override public boolean isAbstract() { return Modifier.

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>isAbstract(_class.getModifiers()); } /** * Convenience method for checking whether underlying Java type * is a concrete class or not: abstract classes and interfaces * are not. */ @Override public boolean isConcrete() { int mod = _class.getModifiers(); if ((mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0) { return true; } /* 19-Feb-2010, tatus: Holy mackarel; primitive types * have 'abstract' flag set... */ return _class.isPrimitive(); } @Override public boolean isThrowable() { return Throwable.class.isAssignableFrom(_class); } @Override public boolean isArrayType() { return false; } @Override public final boolean isEnumType() { return _class.isEnum(); } @Override public final boolean isInterface() { return _class.isInterface(); } @Override public final boolean isPrimitive() { return _class.isPrimitive(); } @Override public final boolean isFinal() { return Modifier.isFinal(_class.getModifiers()); } /** * @return True if type represented is a container type; this includes * array, Map and Collection types. */ @Override public abstract boolean isContainerType(); /** * @return True if type is either true {@link java.util.Collection} type, * or something similar (meaning it has at least one type parameter, * which describes type of contents) */ @Override public boolean isCollectionLikeType() { return false; } /** * @return True if type is either true {@link java.util.Map} type, * or something similar (meaning it has at least two type parameter; * first one describing key type, second value type) */ @Override public boolean isMapLikeType() { return false; } /** * Convenience method, short-hand for *<code> * getRawClass() == Object.class *</code> * and used to figure if we basically have "untyped" type object. * * @since 2.5 */ public final boolean isJavaLangObject() { return _class == Object.class; } /** * Accessor for checking whether handlers for dealing with values of * this type should use static typing (as opposed to dynamic typing). * Note that while value of 'true' does mean that static typing is to * be used, value of 'false' may still be overridden by other settings. * * @since 2.2 */ public final boolean useStaticType() { return _asStatic; }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>); /* /********************************************************** /* Generic attributes (2.3+) /********************************************************** */ /** * Method for accessing attributes available in this context. * Per-call attributes have highest precedence; attributes set * via {@link ObjectReader} or {@link ObjectWriter} have lower * precedence. * * @param key Key of the attribute to get * @return Value of the attribute, if any; null otherwise * * @since 2.3 */ public abstract Object getAttribute(Object key); /** * Method for setting per-call value of given attribute. * This will override any previously defined value for the * attribute within this context. * * @param key Key of the attribute to set * @param value Value to set attribute to * * @return This context object, to allow chaining * * @since 2.3 */ public abstract DatabindContext setAttribute(Object key, Object value); /* /********************************************************** /* Type instantiation/resolution /********************************************************** */ /** * Convenience method for constructing {@link JavaType} for given JDK * type (usually {@link java.lang.Class}) */ public JavaType constructType(Type type) { return getTypeFactory().constructType(type); } /** * Convenience method for constructing subtypes, retaining generic * type parameter (if any) */ public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) { // simple optimization to avoid costly introspection if type-erased type does NOT differ if (baseType.getRawClass() == subclass) { return baseType; } return getConfig().constructSpecializedType(baseType, subclass); } public abstract TypeFactory getTypeFactory(); /* /********************************************************** /* Helper object construction /********************************************************** */ public ObjectIdGenerator<?> objectIdGeneratorInstance(Annotated annotated, ObjectIdInfo objectIdInfo) throws JsonMappingException { Class<?> implClass = objectIdInfo.getGeneratorType(); final MapperConfig<?> config = getConfig(); HandlerInstantiator hi = config.getHandlerInstantiator(); ObjectIdGenerator<?> gen = (hi == null) ? null : hi.objectIdGeneratorInstance(config, annotated, implClass); if (gen == null) { gen = (ObjectIdGenerator<?>) ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers()); } return gen.forScope(objectIdInfo.getScope()); } public ObjectIdResolver objectIdResolverInstance(Annotated annotated, ObjectIdInfo objectIdInfo) { Class<? extends ObjectIdResolver> implClass = objectIdInfo.getResolverType(); final MapperConfig<?> config = getConfig(); HandlerInstanti

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>ator hi = config.getHandlerInstantiator(); ObjectIdResolver resolver = (hi == null) ? null : hi.resolverIdGeneratorInstance(config, annotated, implClass); if (resolver == null) { resolver = ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers()); } return resolver; } /** * Helper method to use to construct a {@link Converter}, given a definition * that may be either actual converter instance, or Class for instantiating one. * * @since 2.2 */ @SuppressWarnings("unchecked") public Converter<Object,Object> converterInstance(Annotated annotated, Object converterDef) throws JsonMappingException { if (converterDef == null) { return null; } if (converterDef instanceof Converter<?,?>) { return (Converter<Object,Object>) converterDef; } if (!(converterDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type " +converterDef.getClass().getName()+"; expected type Converter or Class<Converter> instead"); } Class<?> converterClass = (Class<?>)converterDef; // there are some known "no class" markers to consider too: if (converterClass == Converter.None.class || ClassUtil.isBogusClass(converterClass)) { return null; } if (!Converter.class.isAssignableFrom(converterClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class " +converterClass.getName()+"; expected Class<Converter>"); } final MapperConfig<?> config = getConfig(); HandlerInstantiator hi = config.getHandlerInstantiator(); Converter<?,?> conv = (hi == null) ? null : hi.converterInstance(config, annotated, converterClass); if (conv == null) { conv = (Converter<?,?>) ClassUtil.createInstance(converterClass, config.canOverrideAccessModifiers()); } return (Converter<Object,Object>) conv; } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.type.TypeBindings; import com.fasterxml.jackson.databind.util.Annotations; import com.fasterxml.jackson.databind.util.Converter; /** * Basic container for information gathered by {@link ClassIntrospector} to * help in constructing serializers and deserializers. * Note that the main implementation type is * {@link com.fasterxml.jackson.databind.introspect.BasicBeanDescription}, * meaning that it is safe to upcast to this type. */ public abstract class BeanDescription { /* /********************************************************** /* Configuration /********************************************************** */ /** * Bean type information, including raw class and possible * * generics information */ protected final JavaType _type; /* /********************************************************** /* Life-cycle /********************************************************** */ protected BeanDescription(JavaType type) { _type = type; } /* /********************************************************** /* Simple accesors /********************************************************** */ /** * Method for accessing declared type of bean being introspected, * including full generic type information (from declaration) */ public JavaType getType() { return _type; } public Class<?> getBeanClass() { return _type.getRawClass(); } /** * Method for accessing low-level information about Class this * item describes. */ public abstract AnnotatedClass getClassInfo(); /** * Accessor for getting information about Object Id expected to * be used for this POJO type, if any. */ public abstract ObjectIdInfo getObjectIdInfo(); /** * Method for checking whether class being described has any * annotations recognized by registered annotation introspector. */ public abstract boolean hasKnownClassAnnotations(); /** * Accessor for type bindings that may be needed to fully resolve * types of member object, such as return and argument types of * methods and constructors, and types of fields. * * @deprecated Since 2.7, use {@link #resolveType(java.lang.reflect.Type)} instead. */ @Deprecated public abstract TypeBindings bindingsForBeanType(); /** * Method for resolving given JDK type, using this bean as the * generic type resolution context. */ public abstract JavaType resolveType(java.lang.reflect.Type j

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>cc); if (serializer == null) { // To fix [JACKSON-508] if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } } serializer.serialize(elem, gen, provider); } } catch (IOException ioe) { throw ioe; } catch (Exception e) { // [JACKSON-55] Need to add reference information /* 05-Mar-2009, tatu: But one nasty edge is when we get * StackOverflow: usually due to infinite loop. But that gets * hidden within an InvocationTargetException... */ Throwable t = e; while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) { throw (Error) t; } throw JsonMappingException.wrapWithPath(t, elem, i); } } public void serializeContentsUsing(Object[] value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException { final int len = value.length; final TypeSerializer typeSer = _valueTypeSerializer; int i = 0; Object elem = null; try { for (; i < len; ++i) { elem = value[i]; if (elem == null) { provider.defaultSerializeNull(jgen); continue; } if (typeSer == null) { ser.serialize(elem, jgen, provider); } else { ser.serializeWithType(elem, jgen, provider, typeSer); } } } catch (IOException ioe) { throw ioe; } catch (Exception e) { Throwable t = e; while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) { throw (Error) t; } throw JsonMappingException.wrapWithPath(t, elem, i); } } public void serializeTypedContents(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException { final int len = value.length; final TypeSerializer typeSer = _valueTypeSerializer; int i = 0; Object elem = null; try { PropertySerializerMap serializers = _dynamicSerializers; for (; i < len; ++i) { elem = value[i]; if (elem == null) { provider.default

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>SerializeNull(jgen); continue; } Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { serializer = _findAndAddDynamic(serializers, cc, provider); } serializer.serializeWithType(elem, jgen, provider, typeSer); } } catch (IOException ioe) { throw ioe; } catch (Exception e) { Throwable t = e; while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) { throw (Error) t; } throw JsonMappingException.wrapWithPath(t, elem, i); } } @SuppressWarnings("deprecation") @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { ObjectNode o = createSchemaNode("array", true); if (typeHint != null) { JavaType javaType = provider.constructType(typeHint); if (javaType.isArrayType()) { Class<?> componentType = ((ArrayType) javaType).getContentType().getRawClass(); // 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped? if (componentType == Object.class) { o.set("items", com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode()); } else { JsonSerializer<Object> ser = provider.findValueSerializer(componentType, _property); JsonNode schemaNode = (ser instanceof SchemaAware) ? ((SchemaAware) ser).getSchema(provider, null) : com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode(); o.set("items", schemaNode); } } } return o; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonArrayFormatVisitor arrayVisitor = visitor.expectArrayFormat(typeHint); if (arrayVisitor != null) { TypeFactory tf = visitor.getProvider().getTypeFactory(); JavaType contentType = tf.moreSpecificType(_elementType, typeHint.getContentType()); if (contentType == null) { throw JsonMappingException.from(visitor.getProvider(), "Could not resolve type"); } JsonSerializer<?> valueSer = _elementSerializer; if (valueSer == null) { valueSer = visitor.getProvider().findValueSerializer(contentType, _property); } arrayVisitor.itemsFormat(valueSer, contentType); } } protected

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> visitor; } }, this.getType()); } else { super.depositSchemaProperty(visitor, provider); } } // Override needed to support legacy JSON Schema generator @Override protected void _depositSchemaProperty(ObjectNode propertiesNode, JsonNode schemaNode) { JsonNode props = schemaNode.get("properties"); if (props != null) { Iterator<Entry<String, JsonNode>> it = props.fields(); while (it.hasNext()) { Entry<String,JsonNode> entry = it.next(); String name = entry.getKey(); if (_nameTransformer != null) { name = _nameTransformer.transform(name); } propertiesNode.set(name, entry.getValue()); } } } /* /********************************************************** /* Overrides: internal, other /********************************************************** */ // need to override as we must get unwrapping instance... @Override protected JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, Class<?> type, SerializerProvider provider) throws JsonMappingException { JsonSerializer<Object> serializer; if (_nonTrivialBaseType != null) { JavaType subtype = provider.constructSpecializedType(_nonTrivialBaseType, type); serializer = provider.findValueSerializer(subtype, this); } else { serializer = provider.findValueSerializer(type, this); } NameTransformer t = _nameTransformer; if (serializer.isUnwrappingSerializer()) { t = NameTransformer.chainedTransformer(t, ((UnwrappingBeanSerializer) serializer)._nameTransformer); } serializer = serializer.unwrappingSerializer(t); _dynamicSerializers = _dynamicSerializers.newWith(type, serializer); return serializer; } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> public boolean useForType(JavaType t) { switch (_appliesFor) { case NON_CONCRETE_AND_ARRAYS: while (t.isArrayType()) { t = t.getContentType(); } // fall through case OBJECT_AND_NON_CONCRETE: // 19-Apr-2016, tatu: ReferenceType like Optional also requires similar handling: while (t.isReferenceType()) { t = t.getReferencedType(); } return t.isJavaLangObject() || (!t.isConcrete() // [databind#88] Should not apply to JSON tree models: && !TreeNode.class.isAssignableFrom(t.getRawClass())); case NON_FINAL: while (t.isArrayType()) { t = t.getContentType(); } // 19-Apr-2016, tatu: ReferenceType like Optional also requires similar handling: while (t.isReferenceType()) { t = t.getReferencedType(); } // [databind#88] Should not apply to JSON tree models: return !t.isFinal() && !TreeNode.class.isAssignableFrom(t.getRawClass()); default: //case JAVA_LANG_OBJECT: return t.isJavaLangObject(); } } } /* /********************************************************** /* Internal constants, singletons /********************************************************** */ // Quick little shortcut, to avoid having to use global TypeFactory instance... // 19-Oct-2015, tatu: Not sure if this is really safe to do; let's at least allow // some amount of introspection private final static JavaType JSON_NODE_TYPE = SimpleType.constructUnsafe(JsonNode.class); // TypeFactory.defaultInstance().constructType(JsonNode.class); // 16-May-2009, tatu: Ditto ^^^ protected final static AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR = new JacksonAnnotationIntrospector(); protected final static VisibilityChecker<?> STD_VISIBILITY_CHECKER = VisibilityChecker.Std.defaultInstance(); /** * @deprecated Since 2.6, do not use: will be removed in 2.7 or later */ @Deprecated protected final static PrettyPrinter _defaultPrettyPrinter = new DefaultPrettyPrinter(); /** * Base settings contain defaults used for all {@link ObjectMapper} * instances. */ protected final static BaseSettings DEFAULT_BASE = new BaseSettings( null, // can not share global ClassIntrospector any more (2.5+) DEFAULT_ANNOTATION_INTROSPECTOR, STD_VISIBILITY_CHECK

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> * package) */ @Override public ArrayNode createArrayNode() { return _deserializationConfig.getNodeFactory().arrayNode(); } /** * Method for constructing a {@link JsonParser} out of JSON tree * representation. * * @param n Root node of the tree that resulting parser will read from */ @Override public JsonParser treeAsTokens(TreeNode n) { return new TreeTraversingParser((JsonNode) n, this); } /** * Convenience conversion method that will bind data given JSON tree * contains into specific value (usually bean) type. *<p> * Functionally equivalent to: *<pre> * objectMapper.convertValue(n, valueClass); *</pre> */ @SuppressWarnings("unchecked") @Override public <T> T treeToValue(TreeNode n, Class<T> valueType) throws JsonProcessingException { try { // Simple cast when we just want to cast to, say, ObjectNode // ... one caveat; while everything is Object.class, let's not take shortcut if (valueType != Object.class && valueType.isAssignableFrom(n.getClass())) { return (T) n; } // 20-Apr-2016, tatu: Another thing: for VALUE_EMBEDDED_OBJECT, assume similar // short-cut coercion if (n.asToken() == JsonToken.VALUE_EMBEDDED_OBJECT) { if (n instanceof POJONode) { Object ob = ((POJONode) n).getPojo(); if ((ob == null) || valueType.isInstance(ob)) { return (T) ob; } } } return readValue(treeAsTokens(n), valueType); } catch (JsonProcessingException e) { throw e; } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } } /** * Reverse of {@link #treeToValue}; given a value (usually bean), will * construct equivalent JSON Tree representation. Functionally similar * to serializing value into JSON and parsing JSON as tree, but * more efficient. *<p> * NOTE: while results are usually identical to that of serialization followed * by deserialization, this is not always the case. In some cases serialization * into intermediate representation will retain encapsulation of things like * raw value ({@link com.fasterxml.jackson.databind.util.RawValue}) or basic * node identity ({@link JsonNode}). If so, result is a valid tree, but values * are not re-construct

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> * functionality threw */ @SuppressWarnings("unchecked") public <T> T convertValue(Object fromValue, Class<T> toValueType) throws IllegalArgumentException { // sanity check for null first: if (fromValue == null) return null; return (T) _convert(fromValue, _typeFactory.constructType(toValueType)); } /** * See {@link #convertValue(Object, Class)} */ @SuppressWarnings("unchecked") public <T> T convertValue(Object fromValue, TypeReference<?> toValueTypeRef) throws IllegalArgumentException { return (T) convertValue(fromValue, _typeFactory.constructType(toValueTypeRef)); } /** * See {@link #convertValue(Object, Class)} */ @SuppressWarnings("unchecked") public <T> T convertValue(Object fromValue, JavaType toValueType) throws IllegalArgumentException { // sanity check for null first: if (fromValue == null) return null; return (T) _convert(fromValue, toValueType); } /** * Actual conversion implementation: instead of using existing read * and write methods, much of code is inlined. Reason for this is * that we must avoid root value wrapping/unwrapping both for efficiency and * for correctness. If root value wrapping/unwrapping is actually desired, * caller must use explicit <code>writeValue</code> and * <code>readValue</code> methods. */ @SuppressWarnings("resource") protected Object _convert(Object fromValue, JavaType toValueType) throws IllegalArgumentException { // also, as per [databind#11], consider case for simple cast /* But with caveats: one is that while everything is Object.class, we don't * want to "optimize" that out; and the other is that we also do not want * to lose conversions of generic types. */ Class<?> targetType = toValueType.getRawClass(); if (targetType != Object.class && !toValueType.hasGenericTypes() && targetType.isAssignableFrom(fromValue.getClass())) { return fromValue; } // Then use TokenBuffer, which is a JsonGenerator: TokenBuffer buf = new TokenBuffer(this, false); if (isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) { buf = buf.forceUseOfBigDecimal(true); } try { // inlined 'writeValue' with minor changes: // first: disable wrapping when writing SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE); // no need to check for closing of TokenBuffer _serializerProvider(config).serializeValue(buf, fromValue); // then

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>: as per [databind#840], let's only consider * `true` to have any significance. */ if ((order != null) && order.alphabetic()) { return Boolean.TRUE; } return null; } @Override public void findAndAddVirtualProperties(MapperConfig<?> config, AnnotatedClass ac, List<BeanPropertyWriter> properties) { JsonAppend ann = _findAnnotation(ac, JsonAppend.class); if (ann == null) { return; } final boolean prepend = ann.prepend(); JavaType propType = null; // First: any attribute-backed properties? JsonAppend.Attr[] attrs = ann.attrs(); for (int i = 0, len = attrs.length; i < len; ++i) { if (propType == null) { propType = config.constructType(Object.class); } BeanPropertyWriter bpw = _constructVirtualProperty(attrs[i], config, ac, propType); if (prepend) { properties.add(i, bpw); } else { properties.add(bpw); } } // Then: general-purpose virtual properties? JsonAppend.Prop[] props = ann.props(); for (int i = 0, len = props.length; i < len; ++i) { BeanPropertyWriter bpw = _constructVirtualProperty(props[i], config, ac); if (prepend) { properties.add(i, bpw); } else { properties.add(bpw); } } } protected BeanPropertyWriter _constructVirtualProperty(JsonAppend.Attr attr, MapperConfig<?> config, AnnotatedClass ac, JavaType type) { PropertyMetadata metadata = attr.required() ? PropertyMetadata.STD_REQUIRED : PropertyMetadata.STD_OPTIONAL; // could add Index, Description in future, if those matter String attrName = attr.value(); // allow explicit renaming; if none, default to attribute name PropertyName propName = _propertyName(attr.propName(), attr.propNamespace()); if (!propName.hasSimpleName()) { propName = PropertyName.construct(attrName); } // now, then, we need a placeholder for member (no real Field/Method): AnnotatedMember member = new VirtualAnnotatedMember(ac, ac.getRawType(), attrName, type.getRawClass()); // and with that and property definition SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(config, member, propName, metadata, attr.include()); // can construct the property writer return AttributePropertyWriter.construct(attrName,

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> propDef, ac.getAnnotations(), type); } protected BeanPropertyWriter _constructVirtualProperty(JsonAppend.Prop prop, MapperConfig<?> config, AnnotatedClass ac) { PropertyMetadata metadata = prop.required() ? PropertyMetadata.STD_REQUIRED : PropertyMetadata.STD_OPTIONAL; PropertyName propName = _propertyName(prop.name(), prop.namespace()); JavaType type = config.constructType(prop.type()); // now, then, we need a placeholder for member (no real Field/Method): AnnotatedMember member = new VirtualAnnotatedMember(ac, ac.getRawType(), propName.getSimpleName(), type.getRawClass()); // and with that and property definition SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(config, member, propName, metadata, prop.include()); Class<?> implClass = prop.value(); HandlerInstantiator hi = config.getHandlerInstantiator(); VirtualBeanPropertyWriter bpw = (hi == null) ? null : hi.virtualPropertyWriterInstance(config, implClass); if (bpw == null) { bpw = (VirtualBeanPropertyWriter) ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers()); } // one more thing: give it necessary contextual information return bpw.withConfig(config, ac, propDef, type); } /* /********************************************************** /* Serialization: property annotations /********************************************************** */ @Override public PropertyName findNameForSerialization(Annotated a) { JsonGetter jg = _findAnnotation(a, JsonGetter.class); if (jg != null) { return PropertyName.construct(jg.value()); } JsonProperty pann = _findAnnotation(a, JsonProperty.class); if (pann != null) { return PropertyName.construct(pann.value()); } if (_hasOneOf(a, ANNOTATIONS_TO_INFER_SER)) { return PropertyName.USE_DEFAULT; } return null; } @Override public boolean hasAsValueAnnotation(AnnotatedMethod am) { JsonValue ann = _findAnnotation(am, JsonValue.class); // value of 'false' means disabled... return (ann != null && ann.value()); } /* /********************************************************** /* Deserialization: general annotations /********************************************************** */ @Override public Object findDeserializer(Annotated a) { JsonDeserialize ann = _findAnnotation(a, JsonDeserialize.class); if (ann != null) { @SuppressWarnings("rawtypes") Class<? extends JsonDeserializer> deserClass = ann.using(); if (deserClass != JsonDeserializer.None

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> getSerializer() { return _serializer; } public JavaType getSerializationType() { return _cfgSerializationType; } public Class<?> getRawSerializationType() { return (_cfgSerializationType == null) ? null : _cfgSerializationType.getRawClass(); } /* public JavaType getFullPropertyType() { if (_accessorMethod != null) { return _accessorMethod.getType() } if (_field != null) { return _field.getType(); } return null; } */ /** * @deprecated Since 2.7, to be removed from 2.8, use {@link #getType()} instead. */ @Deprecated public Class<?> getPropertyType() { if (_accessorMethod != null) { return _accessorMethod.getReturnType(); } if (_field != null) { return _field.getType(); } return null; } /** * Get the generic property type of this property writer. * * @return The property type, or null if not found. * * @deprecated Since 2.7, to be removed from 2.8, use {@link #getType()} instead. */ @Deprecated public Type getGenericPropertyType() { if (_accessorMethod != null) { return _accessorMethod.getGenericReturnType(); } if (_field != null) { return _field.getGenericType(); } return null; } public Class<?>[] getViews() { return _includeInViews; } /* /********************************************************** /* PropertyWriter methods (serialization) /********************************************************** */ /** * Method called to access property that this bean stands for, from * within given bean, and to serialize it as a JSON Object field * using appropriate serializer. */ @Override public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception { // inlined 'get()' final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean); // Null handling is bit different, check that first if (value == null) { if (_nullSerializer != null) { gen.writeFieldName(_name); _nullSerializer.serialize(null, gen, prov); } return; } // then find serializer to use JsonSerializer<Object> ser = _serializer; if (ser == null) { Class<?> cls = value.getClass(); PropertySerializerMap m = _dynamicSerializers; ser = m.serializerFor(cls); if (ser == null) { ser = _findAndAddDynamic(m, cls, prov); } } // and then see if we must suppress certain values

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> tabular output serializeAsPlaceholder(bean, gen, prov); return; } } else if (_suppressableValue.equals(value)) { // can NOT suppress entries in tabular output serializeAsPlaceholder(bean, gen, prov); return; } } // For non-nulls: simple check for direct cycles if (value == bean) { if (_handleSelfReference(bean, gen, prov, ser)) { return; } } if (_typeSerializer == null) { ser.serialize(value, gen, prov); } else { ser.serializeWithType(value, gen, prov, _typeSerializer); } } /** * Method called to serialize a placeholder used in tabular output when * real value is not to be included (is filtered out), but when we need * an entry so that field indexes will not be off. Typically this should * output null or empty String, depending on datatype. * * @since 2.1 */ @Override public void serializeAsPlaceholder(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception { if (_nullSerializer != null) { _nullSerializer.serialize(null, gen, prov); } else { gen.writeNull(); } } /* /********************************************************** /* PropertyWriter methods (schema generation) /********************************************************** */ // Also part of BeanProperty implementation @Override public void depositSchemaProperty(JsonObjectFormatVisitor v, SerializerProvider provider) throws JsonMappingException { if (v != null) { if (isRequired()) { v.property(this); } else { v.optionalProperty(this); } } } // // // Legacy support for JsonFormatVisitable /** * Attempt to add the output of the given {@link BeanPropertyWriter} in the given {@link ObjectNode}. * Otherwise, add the default schema {@link JsonNode} in place of the writer's output * * @param propertiesNode Node which the given property would exist within * @param provider Provider that can be used for accessing dynamic aspects of serialization * processing */ @Override @Deprecated public void depositSchemaProperty(ObjectNode propertiesNode, SerializerProvider provider) throws JsonMappingException { JavaType propType = getSerializationType(); // 03-Dec-2010, tatu: SchemaAware REALLY should use JavaType, but alas it doesn't... Type hint = (propType == null) ? getType() : propType.getRawClass(); JsonNode schemaNode; // Maybe it already has annotated/statically configured serializer? JsonSerializer<Object> ser = getSerializer(); if (ser == null

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>) { // nope ser = provider.findValueSerializer(getType(), this); } boolean isOptional = !isRequired(); if (ser instanceof SchemaAware) { schemaNode = ((SchemaAware) ser).getSchema(provider, hint, isOptional) ; } else { schemaNode = com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode(); } _depositSchemaProperty(propertiesNode, schemaNode); } /* /********************************************************** /* Helper methods /********************************************************** */ protected JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, Class<?> type, SerializerProvider provider) throws JsonMappingException { PropertySerializerMap.SerializerAndMapResult result; if (_nonTrivialBaseType != null) { JavaType t = provider.constructSpecializedType(_nonTrivialBaseType, type); result = map.findAndAddPrimarySerializer(t, provider, this); } else { result = map.findAndAddPrimarySerializer(type, provider, this); } // did we get a new map of serializers? If so, start using it if (map != result.map) { _dynamicSerializers = result.map; } return result.serializer; } /** * Method that can be used to access value of the property this * Object describes, from given bean instance. *<p> * Note: method is final as it should not need to be overridden -- rather, * calling method(s) ({@link #serializeAsField}) should be overridden * to change the behavior */ public final Object get(Object bean) throws Exception { return (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean); } /** * Method called to handle a direct self-reference through this property. * Method can choose to indicate an error by throwing {@link JsonMappingException}; * fully handle serialization (and return true); or indicate that it should be * serialized normally (return false). *<p> * Default implementation will throw {@link JsonMappingException} if * {@link SerializationFeature#FAIL_ON_SELF_REFERENCES} is enabled; * or return <code>false</code> if it is disabled. * * @return True if method fully handled self-referential value; false if not (caller * is to handle it) or {@link JsonMappingException} if there is no way handle it */ protected boolean _handleSelfReference(Object bean, JsonGenerator gen, SerializerProvider prov, JsonSerializer<?> ser) throws JsonMappingException { if (prov.isEnabled(SerializationFeature.FAIL_ON_SELF_REFERENCES) && !

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>.Iterable}. *<p> * Note: sub-classes may choose to complete replace implementation, * if they want to alter priority of serializer lookups. */ @Override @SuppressWarnings("unchecked") public JsonSerializer<Object> createSerializer(SerializerProvider prov, JavaType origType) throws JsonMappingException { // Very first thing, let's check if there is explicit serializer annotation: final SerializationConfig config = prov.getConfig(); BeanDescription beanDesc = config.introspect(origType); JsonSerializer<?> ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo()); if (ser != null) { return (JsonSerializer<Object>) ser; } boolean staticTyping; // Next: we may have annotations that further indicate actual type to use (a super type) final AnnotationIntrospector intr = config.getAnnotationIntrospector(); JavaType type = (intr == null) ? origType : intr.refineSerializationType(config, beanDesc.getClassInfo(), origType); if (type == origType) { // no changes, won't force static typing staticTyping = false; } else { // changes; assume static typing; plus, need to re-introspect if class differs staticTyping = true; if (!type.hasRawClass(origType.getRawClass())) { beanDesc = config.introspect(type); } } // Slight detour: do we have a Converter to consider? Converter<Object,Object> conv = beanDesc.findSerializationConverter(); if (conv == null) { // no, simple return (JsonSerializer<Object>) _createSerializer2(prov, type, beanDesc, staticTyping); } JavaType delegateType = conv.getOutputType(prov.getTypeFactory()); // One more twist, as per [databind#288]; probably need to get new BeanDesc if (!delegateType.hasRawClass(type.getRawClass())) { beanDesc = config.introspect(delegateType); // [#359]: explicitly check (again) for @JsonSerializer... ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo()); } // [databind#731]: Should skip if nominally java.lang.Object if (ser == null && !delegateType.isJavaLangObject()) { ser = _createSerializer2(prov, delegateType, beanDesc, true); } return new StdDelegatingSerializer(conv, delegateType, ser); } protected JsonSerializer<?> _createSerializer2(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { JsonSerializer<?> ser = null; final SerializationConfig config = prov.

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> } } } if (ser != null) { // [databind#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifySerializer(config, beanDesc, ser); } } } return ser; } /* /********************************************************** /* Other public methods that are not part of /* JsonSerializerFactory API /********************************************************** */ /** * Method that will try to construct a {@link BeanSerializer} for * given class. Returns null if no properties are found. */ public JsonSerializer<Object> findBeanSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc) throws JsonMappingException { // First things first: we know some types are not beans... if (!isPotentialBeanType(type.getRawClass())) { // 03-Aug-2012, tatu: Except we do need to allow serializers for Enums, // as per [databind#24] if (!type.isEnumType()) { return null; } } return constructBeanSerializer(prov, beanDesc); } /** * @since 2.7 */ public JsonSerializer<?> findReferenceSerializer(SerializerProvider prov, ReferenceType refType, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { JavaType contentType = refType.getContentType(); TypeSerializer contentTypeSerializer = contentType.getTypeHandler(); final SerializationConfig config = prov.getConfig(); if (contentTypeSerializer == null) { contentTypeSerializer = createTypeSerializer(config, contentType); } JsonSerializer<Object> contentSerializer = contentType.getValueHandler(); for (Serializers serializers : customSerializers()) { JsonSerializer<?> ser = serializers.findReferenceSerializer(config, refType, beanDesc, contentTypeSerializer, contentSerializer); if (ser != null) { return ser; } } if (refType.isTypeOrSubTypeOf(AtomicReference.class)) { return new AtomicReferenceSerializer(refType, staticTyping, contentTypeSerializer, contentSerializer); } return null; } /** * Method called to create a type information serializer for values of given * non-container property * if one is needed. If not needed (no polymorphic handling configured), should * return null. * * @param baseType Declared type to use as the base type for type information serializer * * @return Type serializer to use for property values, if one is needed; null if not. */ public TypeSerializer findPropertyTypeSerializer(JavaType baseType, SerializationConfig config, AnnotatedMember accessor) throws

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> */ protected AnnotationMap _classAnnotations; /** * Flag to indicate whether creator information has been resolved * or not. */ protected boolean _creatorsResolved = false; /** * Default constructor of the annotated class, if it has one. */ protected AnnotatedConstructor _defaultConstructor; /** * Single argument constructors the class has, if any. */ protected List<AnnotatedConstructor> _constructors; /** * Single argument static methods that might be usable * as factory methods */ protected List<AnnotatedMethod> _creatorMethods; /** * Member methods of interest; for now ones with 0 or 1 arguments * (just optimization, since others won't be used now) */ protected AnnotatedMethodMap _memberMethods; /** * Member fields of interest: ones that are either public, * or have at least one annotation. */ protected List<AnnotatedField> _fields; /* /********************************************************** /* Life-cycle /********************************************************** */ /** * Constructor will not do any initializations, to allow for * configuring instances differently depending on use cases */ private AnnotatedClass(JavaType type, Class<?> rawType, TypeBindings bindings, List<JavaType> superTypes, AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf, AnnotationMap classAnnotations) { _type = type; _class = rawType; _bindings = bindings; _superTypes = superTypes; _annotationIntrospector = aintr; _typeFactory = tf; _mixInResolver = mir; _primaryMixIn = (_mixInResolver == null) ? null : _mixInResolver.findMixInClassFor(_class); _classAnnotations = classAnnotations; } @Override public AnnotatedClass withAnnotations(AnnotationMap ann) { return new AnnotatedClass(_type, _class, _bindings, _superTypes, _annotationIntrospector, _mixInResolver, _typeFactory, ann); } /** * Factory method that instantiates an instance. Returned instance * will only be initialized with class annotations, but not with * any method information. * * @since 2.7 */ public static AnnotatedClass construct(JavaType type, MapperConfig<?> config) { AnnotationIntrospector intr = config.isAnnotationProcessingEnabled() ? config.getAnnotationIntrospector() : null; Class<?> raw = type.getRawClass(); return new AnnotatedClass(type, raw, type.getBindings(), ClassUtil.findSuperTypes(type, null, false), intr, (MixInResolver) config, config.getTypeFactory(), null); } /**

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> * @since 2.7 */ public static AnnotatedClass construct(JavaType type, MapperConfig<?> config, MixInResolver mir) { AnnotationIntrospector intr = config.isAnnotationProcessingEnabled() ? config.getAnnotationIntrospector() : null; Class<?> raw = type.getRawClass(); return new AnnotatedClass(type, raw, type.getBindings(), ClassUtil.findSuperTypes(type, null, false), intr, mir, config.getTypeFactory(), null); } /** * Method similar to {@link #construct}, but that will NOT include * information from supertypes; only class itself and any direct * mix-ins it may have. */ public static AnnotatedClass constructWithoutSuperTypes(Class<?> cls, MapperConfig<?> config) { if (config == null) { return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(), Collections.<JavaType>emptyList(), null, null, null, null); } AnnotationIntrospector intr = config.isAnnotationProcessingEnabled() ? config.getAnnotationIntrospector() : null; return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(), Collections.<JavaType>emptyList(), intr, (MixInResolver) config, config.getTypeFactory(), null); } public static AnnotatedClass constructWithoutSuperTypes(Class<?> cls, MapperConfig<?> config, MixInResolver mir) { if (config == null) { return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(), Collections.<JavaType>emptyList(), null, null, null, null); } AnnotationIntrospector intr = config.isAnnotationProcessingEnabled() ? config.getAnnotationIntrospector() : null; return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(), Collections.<JavaType>emptyList(), intr, mir, config.getTypeFactory(), null); } /* /********************************************************** /* TypeResolutionContext implementation /********************************************************** */ @Override public JavaType resolveType(Type type) { return _typeFactory.constructType(type, _bindings); } /* /********************************************************** /* Annotated impl /********************************************************** */ @Override public Class<?> getAnnotated() { return _class; } @Override public int getModifiers() { return _class.getModifiers(); } @Override public String getName() { return _class.getName(); } @Override public <A extends Annotation> A getAnnotation(Class<A> acls) { return _classAnnotations().get(acls); } @Override public boolean hasAnnotation(Class<?> acls) { return _classAnnotations().has

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> class annotations are needed synchronized (this) { anns = _classAnnotations; if (anns == null) { anns = _resolveClassAnnotations(); _classAnnotations = anns; } } } return anns; } /** * Initialization method that will recursively collect Jackson * annotations for this class and all super classes and * interfaces. */ private AnnotationMap _resolveClassAnnotations() { AnnotationMap ca = new AnnotationMap(); // Should skip processing if annotation processing disabled if (_annotationIntrospector != null) { // add mix-in annotations first (overrides) if (_primaryMixIn != null) { _addClassMixIns(ca, _class, _primaryMixIn); } // first, annotations from the class itself: _addAnnotationsIfNotPresent(ca, ClassUtil.findClassAnnotations(_class)); // and then from super types for (JavaType type : _superTypes) { // and mix mix-in annotations in-between _addClassMixIns(ca, type); _addAnnotationsIfNotPresent(ca, ClassUtil.findClassAnnotations(type.getRawClass())); } /* and finally... any annotations there might be for plain * old Object.class: separate because for all other purposes * it is just ignored (not included in super types) */ /* 12-Jul-2009, tatu: Should this be done for interfaces too? * For now, yes, seems useful for some cases, and not harmful for any? */ _addClassMixIns(ca, Object.class); } return ca; } /** * Initialization method that will find out all constructors * and potential static factory methods the class has. */ private void resolveCreators() { // Then see which constructors we have List<AnnotatedConstructor> constructors = null; ClassUtil.Ctor[] declaredCtors = ClassUtil.getConstructors(_class); // Constructor also always members of this class TypeResolutionContext typeContext = this; // 30-Apr-2016, tatu: [databind#1215]: Actually, while true, this does // NOT apply to context since sub-class may have type bindings // TypeResolutionContext typeContext = new TypeResolutionContext.Basic(_typeFactory, _type.getBindings()); for (ClassUtil.Ctor ctor : declaredCtors) { if (_isIncludableConstructor(ctor.getConstructor())) { if (ctor.getParamCount() == 0) { _defaultConstructor = _constructDefaultConstructor(ctor, typeContext); } else { if (constructors == null) { constructors = new

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> * @param methodFilter Filter used to determine which methods to include */ private void resolveMemberMethods() { _memberMethods = new AnnotatedMethodMap(); AnnotatedMethodMap mixins = new AnnotatedMethodMap(); // first: methods from the class itself _addMemberMethods(_class, this, _memberMethods, _primaryMixIn, mixins); // and then augment these with annotations from super-types: for (JavaType type : _superTypes) { Class<?> mixin = (_mixInResolver == null) ? null : _mixInResolver.findMixInClassFor(type.getRawClass()); _addMemberMethods(type.getRawClass(), new TypeResolutionContext.Basic(_typeFactory, type.getBindings()), _memberMethods, mixin, mixins); } // Special case: mix-ins for Object.class? (to apply to ALL classes) if (_mixInResolver != null) { Class<?> mixin = _mixInResolver.findMixInClassFor(Object.class); if (mixin != null) { _addMethodMixIns(_class, _memberMethods, mixin, mixins); } } /* Any unmatched mix-ins? Most likely error cases (not matching * any method); but there is one possible real use case: * exposing Object#hashCode (alas, Object#getClass can NOT be * exposed) */ // 14-Feb-2011, tatu: AnnotationIntrospector is null if annotations not enabled; if so, can skip: if (_annotationIntrospector != null) { if (!mixins.isEmpty()) { Iterator<AnnotatedMethod> it = mixins.iterator(); while (it.hasNext()) { AnnotatedMethod mixIn = it.next(); try { Method m = Object.class.getDeclaredMethod(mixIn.getName(), mixIn.getRawParameterTypes()); if (m != null) { // Since it's from java.lang.Object, no generics, no need for real type context: AnnotatedMethod am = _constructMethod(m, this); _addMixOvers(mixIn.getAnnotated(), am, false); _memberMethods.add(am); } } catch (Exception e) { } } } } } /** * Method that will collect all member (non-static) fields * that are either public, or have at least a single annotation * associated with them. */ private void resolveFields() { Map<String,AnnotatedField> foundFields = _findFields(_type, this, null); if (foundFields == null || foundFields.size() == 0) { _fields = Collections.emptyList(); } else

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> { _fields = new ArrayList<AnnotatedField>(foundFields.size()); _fields.addAll(foundFields.values()); } } /* /********************************************************** /* Helper methods for resolving class annotations /* (resolution consisting of inheritance, overrides, /* and injection of mix-ins as necessary) /********************************************************** */ /** * Helper method for adding any mix-in annotations specified * class might have. */ protected void _addClassMixIns(AnnotationMap annotations, JavaType target) { if (_mixInResolver != null) { final Class<?> toMask = target.getRawClass(); _addClassMixIns(annotations, toMask, _mixInResolver.findMixInClassFor(toMask)); } } protected void _addClassMixIns(AnnotationMap annotations, Class<?> target) { if (_mixInResolver != null) { _addClassMixIns(annotations, target, _mixInResolver.findMixInClassFor(target)); } } protected void _addClassMixIns(AnnotationMap annotations, Class<?> toMask, Class<?> mixin) { if (mixin == null) { return; } // Ok, first: annotations from mix-in class itself: _addAnnotationsIfNotPresent(annotations, ClassUtil.findClassAnnotations(mixin)); /* And then from its supertypes, if any. But note that we will * only consider super-types up until reaching the masked * class (if found); this because often mix-in class * is a sub-class (for convenience reasons). And if so, we * absolutely must NOT include super types of masked class, * as that would inverse precedence of annotations. */ for (Class<?> parent : ClassUtil.findSuperClasses(mixin, toMask, false)) { _addAnnotationsIfNotPresent(annotations, ClassUtil.findClassAnnotations(parent)); } } /* /********************************************************** /* Helper methods for populating creator (ctor, factory) information /********************************************************** */ protected void _addConstructorMixIns(Class<?> mixin) { MemberKey[] ctorKeys = null; int ctorCount = (_constructors == null) ? 0 : _constructors.size(); for (ClassUtil.Ctor ctor0 : ClassUtil.getConstructors(mixin)) { Constructor<?> ctor = ctor0.getConstructor(); if (ctor.getParameterTypes().length == 0) { if (_defaultConstructor != null) { _addMixOvers(ctor, _defaultConstructor, false); } } else { if (ctorKeys == null) { ctorKeys = new MemberKey[ctorCount]; for (int i = 0; i < ctorCount; ++

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>, TypeResolutionContext typeContext, Map<String,AnnotatedField> fields) { /* First, a quick test: we only care for regular classes (not * interfaces, primitive types etc), except for Object.class. * A simple check to rule out other cases is to see if there * is a super class or not. */ JavaType parent = type.getSuperClass(); if (parent != null) { final Class<?> cls = type.getRawClass(); // Let's add super-class' fields first, then ours. /* 21-Feb-2010, tatu: Need to handle masking: as per [JACKSON-226] * we otherwise get into trouble... */ fields = _findFields(parent, new TypeResolutionContext.Basic(_typeFactory, parent.getBindings()), fields); for (Field f : ClassUtil.getDeclaredFields(cls)) { // static fields not included (transients are at this point, filtered out later) if (!_isIncludableField(f)) { continue; } /* Ok now: we can (and need) not filter out ignorable fields * at this point; partly because mix-ins haven't been * added, and partly because logic can be done when * determining get/settability of the field. */ if (fields == null) { fields = new LinkedHashMap<String,AnnotatedField>(); } fields.put(f.getName(), _constructField(f, typeContext)); } // And then... any mix-in overrides? if (_mixInResolver != null) { Class<?> mixin = _mixInResolver.findMixInClassFor(cls); if (mixin != null) { _addFieldMixIns(mixin, cls, fields); } } } return fields; } /** * Method called to add field mix-ins from given mix-in class (and its fields) * into already collected actual fields (from introspected classes and their * super-classes) */ protected void _addFieldMixIns(Class<?> mixInCls, Class<?> targetClass, Map<String,AnnotatedField> fields) { List<Class<?>> parents = ClassUtil.findSuperClasses(mixInCls, targetClass, true); for (Class<?> mixin : parents) { for (Field mixinField : ClassUtil.getDeclaredFields(mixin)) { // there are some dummy things (static, synthetic); better ignore if (!_isIncludableField(mixinField)) { continue; } String name = mixinField.getName(); // anything to mask? (if not, quietly ignore) Annotated

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> */ @Override public boolean hasGetter() { return _getters != null; } @Override public boolean hasSetter() { return _setters != null; } @Override public boolean hasField() { return _fields != null; } @Override public boolean hasConstructorParameter() { return _ctorParameters != null; } @Override public boolean couldDeserialize() { return (_ctorParameters != null) || (_setters != null) || (_fields != null); } @Override public boolean couldSerialize() { return (_getters != null) || (_fields != null); } @Override public AnnotatedMethod getGetter() { // Easy with zero or one getters... Linked<AnnotatedMethod> curr = _getters; if (curr == null) { return null; } Linked<AnnotatedMethod> next = curr.next; if (next == null) { return curr.value; } // But if multiple, verify that they do not conflict... for (; next != null; next = next.next) { /* [JACKSON-255] Allow masking, i.e. do not report exception if one * is in super-class from the other */ Class<?> currClass = curr.value.getDeclaringClass(); Class<?> nextClass = next.value.getDeclaringClass(); if (currClass != nextClass) { if (currClass.isAssignableFrom(nextClass)) { // next is more specific curr = next; continue; } if (nextClass.isAssignableFrom(currClass)) { // current more specific continue; } } /* 30-May-2014, tatu: Three levels of precedence: * * 1. Regular getters ("getX") * 2. Is-getters ("isX") * 3. Implicit, possible getters ("x") */ int priNext = _getterPriority(next.value); int priCurr = _getterPriority(curr.value); if (priNext != priCurr) { if (priNext < priCurr) { curr = next; } continue; } throw new IllegalArgumentException("Conflicting getter definitions for property \""+getName()+"\": " +curr.value.getFullName()+" vs "+next.value.getFullName()); } // One more thing; to avoid having to do it again... _getters = curr.withoutNext(); return curr.value; } @Override public AnnotatedMethod getSetter() { // Easy with zero or one getters... Linked<AnnotatedMethod> curr = _setters; if (curr == null) { return null;

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> } Linked<AnnotatedMethod> next = curr.next; if (next == null) { return curr.value; } // But if multiple, verify that they do not conflict... for (; next != null; next = next.next) { // Allow masking, i.e. do not fail if one is in super-class from the other Class<?> currClass = curr.value.getDeclaringClass(); Class<?> nextClass = next.value.getDeclaringClass(); if (currClass != nextClass) { if (currClass.isAssignableFrom(nextClass)) { // next is more specific curr = next; continue; } if (nextClass.isAssignableFrom(currClass)) { // current more specific continue; } } AnnotatedMethod nextM = next.value; AnnotatedMethod currM = curr.value; /* 30-May-2014, tatu: Two levels of precedence: * * 1. Regular setters ("setX(...)") * 2. Implicit, possible setters ("x(...)") */ int priNext = _setterPriority(nextM); int priCurr = _setterPriority(currM); if (priNext != priCurr) { if (priNext < priCurr) { curr = next; } continue; } // 11-Dec-2015, tatu: As per [databind#1033] allow pluggable conflict resolution if (_annotationIntrospector != null) { AnnotatedMethod pref = _annotationIntrospector.resolveSetterConflict(_config, currM, nextM); // note: should be one of nextM/currM; but no need to check if (pref == currM) { continue; } if (pref == nextM) { curr = next; continue; } } throw new IllegalArgumentException("Conflicting setter definitions for property \""+getName()+"\": " +curr.value.getFullName()+" vs "+next.value.getFullName()); } // One more thing; to avoid having to do it again... _setters = curr.withoutNext(); return curr.value; } @Override public AnnotatedField getField() { if (_fields == null) { return null; } // If multiple, verify that they do not conflict... AnnotatedField field = _fields.value; Linked<AnnotatedField> next = _fields.next; for (; next != null; next = next.next) { AnnotatedField nextField = next.value; Class<?> fieldClass = field.getDeclaringClass(); Class<?> nextClass = next

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Field.getDeclaringClass(); if (fieldClass != nextClass) { if (fieldClass.isAssignableFrom(nextClass)) { // next is more specific field = nextField; continue; } if (nextClass.isAssignableFrom(fieldClass)) { // getter more specific continue; } } throw new IllegalArgumentException("Multiple fields representing property \""+getName()+"\": " +field.getFullName()+" vs "+nextField.getFullName()); } return field; } @Override public AnnotatedParameter getConstructorParameter() { if (_ctorParameters == null) { return null; } /* Hmmh. Checking for constructor parameters is trickier; for one, * we must allow creator and factory method annotations. * If this is the case, constructor parameter has the precedence. * * So, for now, just try finding the first constructor parameter; * if none, first factory method. And don't check for dups, if we must, * can start checking for them later on. */ Linked<AnnotatedParameter> curr = _ctorParameters; do { if (curr.value.getOwner() instanceof AnnotatedConstructor) { return curr.value; } curr = curr.next; } while (curr != null); return _ctorParameters.value; } @Override public Iterator<AnnotatedParameter> getConstructorParameters() { if (_ctorParameters == null) { return ClassUtil.emptyIterator(); } return new MemberIterator<AnnotatedParameter>(_ctorParameters); } @Override public AnnotatedMember getAccessor() { AnnotatedMember m = getGetter(); if (m == null) { m = getField(); } return m; } @Override public AnnotatedMember getMutator() { AnnotatedMember m = getConstructorParameter(); if (m == null) { m = getSetter(); if (m == null) { m = getField(); } } return m; } @Override public AnnotatedMember getNonConstructorMutator() { AnnotatedMember m = getSetter(); if (m == null) { m = getField(); } return m; } @Override public AnnotatedMember getPrimaryMember() { if (_forSerialization) { return getAccessor(); } return getMutator(); } protected int _getterPriority(AnnotatedMethod m) { final String name = m.getName(); // [databind#238]: Also, regular getters have precedence over "is-getters" if (name.startsWith("get") && name.length() > 3) { // should we check capitalization? return

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> if (valueElem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = valueElem.getClass(); JsonSerializer<Object> ser = serializers.serializerFor(cc); if (ser == null) { if (_valueType.hasGenericTypes()) { ser = _findAndAddDynamic(serializers, provider.constructSpecializedType(_valueType, cc), provider); } else { ser = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicValueSerializers; } try { if (vts == null) { ser.serialize(valueElem, jgen, provider); } else { ser.serializeWithType(valueElem, jgen, provider, vts); } } catch (Exception e) { // [JACKSON-55] Need to add reference information String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } /** * Method called to serialize fields, when the value type is statically known, * so that value serializer is passed and does not need to be fetched from * provider. */ protected void serializeUsing(Map.Entry<?, ?> value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException, JsonGenerationException { final JsonSerializer<Object> keySerializer = _keySerializer; final TypeSerializer vts = _valueTypeSerializer; final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES); Object valueElem = value.getValue(); Object keyElem = value.getKey(); if (keyElem == null) { provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider); } else { // [JACKSON-314] also may need to skip entries with null values if (skipNulls && valueElem == null) return; keySerializer.serialize(keyElem, jgen, provider); } if (valueElem == null) { provider.defaultSerializeNull(jgen); } else { try { if (vts == null) { ser.serialize(valueElem, jgen, provider); } else { ser.serializeWithType(valueElem, jgen, provider, vts); } } catch (Exception e) { // [JACKSON-55] Need to add reference information String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } /* /********************************************************** /* Internal helper methods /********************************************************** */ protected final JsonSerializer<

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> } @Override public void serializeContents(List<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException { if (_elementSerializer != null) { serializeContentsUsing(value, jgen, provider, _elementSerializer); return; } if (_valueTypeSerializer != null) { serializeTypedContents(value, jgen, provider); return; } final int len = value.size(); if (len == 0) { return; } int i = 0; try { PropertySerializerMap serializers = _dynamicSerializers; for (; i < len; ++i) { Object elem = value.get(i); if (elem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { // To fix [JACKSON-508] if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicSerializers; } serializer.serialize(elem, jgen, provider); } } } catch (Exception e) { wrapAndThrow(provider, e, value, i); } } public void serializeContentsUsing(List<?> value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException { final int len = value.size(); if (len == 0) { return; } final TypeSerializer typeSer = _valueTypeSerializer; for (int i = 0; i < len; ++i) { Object elem = value.get(i); try { if (elem == null) { provider.defaultSerializeNull(jgen); } else if (typeSer == null) { ser.serialize(elem, jgen, provider); } else { ser.serializeWithType(elem, jgen, provider, typeSer); } } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, i); } } } public void serializeTypedContents(List<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException { final int len = value.size(); if (len == 0) { return; } int i = 0; try { final TypeSerializer typeSer = _valueTypeSerializer; PropertySerializerMap serializers

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> = _dynamicSerializers; for (; i < len; ++i) { Object elem = value.get(i); if (elem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { // To fix [JACKSON-508] if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicSerializers; } serializer.serializeWithType(elem, jgen, provider, typeSer); } } } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, i); } } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>deserFeatures; } /* /********************************************************** /* Other configuration /********************************************************** */ /** * Method for getting head of the problem handler chain. May be null, * if no handlers have been added. */ public LinkedNode<DeserializationProblemHandler> getProblemHandlers() { return _problemHandlers; } public final JsonNodeFactory getNodeFactory() { return _nodeFactory; } /* /********************************************************** /* Introspection methods /********************************************************** */ /** * Method that will introspect full bean properties for the purpose * of building a bean deserializer * * @param type Type of class to be introspected */ @SuppressWarnings("unchecked") public <T extends BeanDescription> T introspect(JavaType type) { return (T) getClassIntrospector().forDeserialization(this, type, this); } /** * Method that will introspect subset of bean properties needed to * construct bean instance. */ @SuppressWarnings("unchecked") public <T extends BeanDescription> T introspectForCreation(JavaType type) { return (T) getClassIntrospector().forCreation(this, type, this); } /** * @since 2.0 */ @SuppressWarnings("unchecked") public <T extends BeanDescription> T introspectForBuilder(JavaType type) { return (T) getClassIntrospector().forDeserializationWithBuilder(this, type, this); } /* /********************************************************** /* Support for polymorphic type handling /********************************************************** */ /** * Helper method that is needed to properly handle polymorphic referenced * types, such as types referenced by {@link java.util.concurrent.atomic.AtomicReference}, * or various "optional" types. * * @since 2.4 */ public TypeDeserializer findTypeDeserializer(JavaType baseType) throws JsonMappingException { BeanDescription bean = introspectClassAnnotations(baseType.getRawClass()); AnnotatedClass ac = bean.getClassInfo(); TypeResolverBuilder<?> b = getAnnotationIntrospector().findTypeResolver(this, ac, baseType); /* Ok: if there is no explicit type info handler, we may want to * use a default. If so, config object knows what to use. */ Collection<NamedType> subtypes = null; if (b == null) { b = getDefaultTyper(baseType); if (b == null) { return null; } } else { subtypes = getSubtypeResolver().collectAndResolveSubtypesByTypeId(this, ac); } /* 04-May-2014, tatu: When called from DeserializerFactory, additional code

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.introspect; import java.lang.reflect.*; import com.fasterxml.jackson.databind.JavaType; /** * Object that represents method parameters, mostly so that associated * annotations can be processed conveniently. Note that many of accessors * can not return meaningful values since parameters do not have stand-alone * JDK objects associated; so access should mostly be limited to checking * annotation values which are properly aggregated and included. */ public final class AnnotatedParameter extends AnnotatedMember { private static final long serialVersionUID = 1L; /** * Member (method, constructor) that this parameter belongs to */ protected final AnnotatedWithParams _owner; /** * JDK type of the parameter, possibly contains generic type information */ protected final JavaType _type; /** * Index of the parameter within argument list */ protected final int _index; /* /********************************************************** /* Life-cycle /********************************************************** */ public AnnotatedParameter(AnnotatedWithParams owner, JavaType type, AnnotationMap annotations, int index) { super((owner == null) ? null : owner.getTypeContext(), annotations); _owner = owner; _type = type; _index = index; } @Override public AnnotatedParameter withAnnotations(AnnotationMap ann) { if (ann == _annotations) { return this; } return _owner.replaceParameterAnnotations(_index, ann); } /* /********************************************************** /* Annotated impl /********************************************************** */ /** * Since there is no matching JDK element, this method will * always return null */ @Override public AnnotatedElement getAnnotated() { return null; } /** * Returns modifiers of the constructor, as parameters do not * have independent modifiers. */ @Override public int getModifiers() { return _owner.getModifiers(); } /** * Parameters have no names in bytecode (unlike in source code), * will always return empty String (""). */ @Override public String getName() { return ""; } @Override public Class<?> getRawType() { return _type.getRawClass(); } @Override public JavaType getType() { return _typeContext.resolveType(_type); } /* /********************************************************** /* AnnotatedMember extras /********************************************************** */ @Override public Class<?> getDeclaringClass() { return _owner.getDeclaringClass(); } @Override public Member getMember() { /* This is bit tricky: since there is no JDK equivalent; can either * return null or owner... let's do latter, for now. */ return _owner.

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>Result(serializer, newWith(type.getRawClass(), serializer)); } /** * Method called if initial lookup fails, when looking for a non-primary * serializer (one that is not directly attached to a property). * Will both find serializer * and construct new map instance if warranted, and return both. * * @since 2.3 * * @throws JsonMappingException */ public final SerializerAndMapResult findAndAddSecondarySerializer(Class<?> type, SerializerProvider provider, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> serializer = provider.findValueSerializer(type, property); return new SerializerAndMapResult(serializer, newWith(type, serializer)); } public final SerializerAndMapResult findAndAddSecondarySerializer(JavaType type, SerializerProvider provider, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> serializer = provider.findValueSerializer(type, property); return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer)); } /** * Method called if initial lookup fails, when looking for a root value * serializer: one that is not directly attached to a property, but needs to * have {@link com.fasterxml.jackson.databind.jsontype.TypeSerializer} wrapped * around it. Will both find the serializer * and construct new map instance if warranted, and return both. * * @since 2.5 * * @throws JsonMappingException */ public final SerializerAndMapResult findAndAddRootValueSerializer(Class<?> type, SerializerProvider provider) throws JsonMappingException { JsonSerializer<Object> serializer = provider.findTypedValueSerializer(type, false, null); return new SerializerAndMapResult(serializer, newWith(type, serializer)); } /** * @since 2.5 */ public final SerializerAndMapResult findAndAddRootValueSerializer(JavaType type, SerializerProvider provider) throws JsonMappingException { JsonSerializer<Object> serializer = provider.findTypedValueSerializer(type, false, null); return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer)); } /** * Method called if initial lookup fails, when looking for a key * serializer (possible attached indirectly to a property) * Will both find serializer * and construct new map instance if warranted, and return both. * * @since 2.7 */ public final SerializerAndMapResult findAndAddKeySerializer(Class<?> type, SerializerProvider provider, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> serializer = provider.findKeySerializer(type, property); return

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> new SerializerAndMapResult(serializer, newWith(type, serializer)); } /** * Method that can be used to 'register' a serializer that caller has resolved * without help of this map. * * @since 2.5 */ public final SerializerAndMapResult addSerializer(Class<?> type, JsonSerializer<Object> serializer) { return new SerializerAndMapResult(serializer, newWith(type, serializer)); } /** * @since 2.5 */ public final SerializerAndMapResult addSerializer(JavaType type, JsonSerializer<Object> serializer) { return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer)); } public abstract PropertySerializerMap newWith(Class<?> type, JsonSerializer<Object> serializer); /** * @deprecated Since 2.5 Use {@link #emptyForProperties} instead */ @Deprecated public static PropertySerializerMap emptyMap() { return emptyForProperties(); } /** * @since 2.5 */ public static PropertySerializerMap emptyForProperties() { return Empty.FOR_PROPERTIES; } /** * @since 2.5 */ public static PropertySerializerMap emptyForRootValues() { return Empty.FOR_ROOT_VALUES; } /* /********************************************************** /* Helper classes /********************************************************** */ /** * Value class used for returning tuple that has both serializer * that was retrieved and new map instance */ public final static class SerializerAndMapResult { public final JsonSerializer<Object> serializer; public final PropertySerializerMap map; public SerializerAndMapResult(JsonSerializer<Object> serializer, PropertySerializerMap map) { this.serializer = serializer; this.map = map; } } /** * Trivial container for bundling type + serializer entries. */ private final static class TypeAndSerializer { public final Class<?> type; public final JsonSerializer<Object> serializer; public TypeAndSerializer(Class<?> type, JsonSerializer<Object> serializer) { this.type = type; this.serializer = serializer; } } /* /********************************************************** /* Implementations /********************************************************** */ /** * Bogus instance that contains no serializers; used as the default * map with new serializers. */ private final static class Empty extends PropertySerializerMap { // No root serializers; do not reset when full public final static Empty FOR_PROPERTIES = new Empty(false); // Yes, root serializers; do reset when full public final static Empty FOR_ROOT_VALUES = new Empty(true); protected Empty(boolean resetWhenFull) { super(resetWhenFull); } @Override

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.JsonParser.NumberType; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import com.fasterxml.jackson.databind.jsonFormatVisitors.*; import com.fasterxml.jackson.databind.jsonschema.SchemaAware; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.ser.PropertyFilter; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.Converter; /** * Base class used by all standard serializers, and can also * be used for custom serializers (in fact, this is the recommended * base class to use). * Provides convenience methods for implementing {@link SchemaAware} */ public abstract class StdSerializer<T> extends JsonSerializer<T> implements JsonFormatVisitable, SchemaAware, java.io.Serializable { /** * Unique key we use to store a temporary lock, to prevent infinite recursion * when resolving content converters (see [databind#357]). *<p> * NOTE: may need to revisit this if nested content converters are needed; if so, * may need to create per-call lock object. But let's start with a simpler * solution for now. * * @since 2.7 */ private final static Object CONVERTING_CONTENT_CONVERTER_LOCK = new Object(); private static final long serialVersionUID = 1L; /** * Nominal type supported, usually declared type of * property for which serializer is used. */ protected final Class<T> _handledType; /* /********************************************************** /* Life-cycle /********************************************************** */ protected StdSerializer(Class<T> t) { _handledType = t; } @SuppressWarnings("unchecked") protected StdSerializer(JavaType type) { _handledType = (Class<T>) type.getRawClass(); } /** * Alternate constructor that is (alas!) needed to work * around kinks of generic type handling */ @SuppressWarnings("unchecked") protected StdSerializer(

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> { return _collectionType.getContentType(); } @Override public JsonDeserializer<Object> getContentDeserializer() { return _valueDeserializer; } /* /********************************************************** /* JsonDeserializer API /********************************************************** */ @SuppressWarnings("unchecked") @Override public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { if (_delegateDeserializer != null) { return (Collection<Object>) _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt)); } /* [JACKSON-620]: empty String may be ok; bit tricky to check, however, since * there is also possibility of "auto-wrapping" of single-element arrays. * Hence we only accept empty String here. */ if (p.hasToken(JsonToken.VALUE_STRING)) { String str = p.getText(); if (str.length() == 0) { return (Collection<Object>) _valueInstantiator.createFromString(ctxt, str); } } return deserialize(p, ctxt, (Collection<Object>) _valueInstantiator.createUsingDefault(ctxt)); } @Override public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt, Collection<Object> result) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!p.isExpectedStartArrayToken()) { return handleNonArray(p, ctxt, result); } // [databind#631]: Assign current value, to be accessible by custom serializers p.setCurrentValue(result); JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; CollectionReferringAccumulator referringAccumulator = (valueDes.getObjectIdReader() == null) ? null : new CollectionReferringAccumulator(_collectionType.getContentType().getRawClass(), result); JsonToken t; while ((t = p.nextToken()) != JsonToken.END_ARRAY) { try { Object value; if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(ctxt); } else if (typeDeser == null) { value = valueDes.deserialize(p, ctxt); } else { value = valueDes.deserializeWithType(p, ctxt, typeDeser); } if (referringAccumulator != null) { referringAccumulator.add(value); } else { result.add(value); } } catch (UnresolvedForwardReference reference) { if (referringAccumulator == null) { throw JsonMappingException .from(p, "Unresolved forward reference

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> but no identity info", reference); } Referring ref = referringAccumulator.handleUnresolvedReference(reference); reference.getRoid().appendReferring(ref); } catch (Exception e) { boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS); if (!wrap && e instanceof RuntimeException) { throw (RuntimeException)e; } throw JsonMappingException.wrapWithPath(e, result, result.size()); } } return result; } @Override public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException { // In future could check current token... for now this should be enough: return typeDeserializer.deserializeTypedFromArray(jp, ctxt); } /** * Helper method called when current token is no START_ARRAY. Will either * throw an exception, or try to handle value as if member of implicit * array, depending on configuration. */ protected final Collection<Object> handleNonArray(JsonParser p, DeserializationContext ctxt, Collection<Object> result) throws IOException { // Implicit arrays from single values? boolean canWrap = (_unwrapSingle == Boolean.TRUE) || ((_unwrapSingle == null) && ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)); if (!canWrap) { throw ctxt.mappingException(_collectionType.getRawClass()); } JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; JsonToken t = p.getCurrentToken(); Object value; try { if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(ctxt); } else if (typeDeser == null) { value = valueDes.deserialize(p, ctxt); } else { value = valueDes.deserializeWithType(p, ctxt, typeDeser); } } catch (Exception e) { // note: pass Object.class, not Object[].class, as we need element type for error info throw JsonMappingException.wrapWithPath(e, Object.class, result.size()); } result.add(value); return result; } public final static class CollectionReferringAccumulator { private final Class<?> _elementType; private final Collection<Object> _result; /** * A list of {@link CollectionReferring} to maintain ordering. */ private List<CollectionReferring> _accumulator = new ArrayList<CollectionReferring>(); public CollectionReferringAccumulator(Class<?> elementType, Collection<Object> result) { _elementType = elementType; _result = result; }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> fluent factories /******************************************************** */ /** * Convenience method for creating a new factory instance with additional deserializer * provider. */ @Override public final DeserializerFactory withAdditionalDeserializers(Deserializers additional) { return withConfig(_factoryConfig.withAdditionalDeserializers(additional)); } /** * Convenience method for creating a new factory instance with additional * {@link KeyDeserializers}. */ @Override public final DeserializerFactory withAdditionalKeyDeserializers(KeyDeserializers additional) { return withConfig(_factoryConfig.withAdditionalKeyDeserializers(additional)); } /** * Convenience method for creating a new factory instance with additional * {@link BeanDeserializerModifier}. */ @Override public final DeserializerFactory withDeserializerModifier(BeanDeserializerModifier modifier) { return withConfig(_factoryConfig.withDeserializerModifier(modifier)); } /** * Convenience method for creating a new factory instance with additional * {@link AbstractTypeResolver}. */ @Override public final DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver) { return withConfig(_factoryConfig.withAbstractTypeResolver(resolver)); } /** * Convenience method for creating a new factory instance with additional * {@link ValueInstantiators}. */ @Override public final DeserializerFactory withValueInstantiators(ValueInstantiators instantiators) { return withConfig(_factoryConfig.withValueInstantiators(instantiators)); } /* /********************************************************** /* DeserializerFactory impl (partial): type mappings /********************************************************** */ @Override public JavaType mapAbstractType(DeserializationConfig config, JavaType type) throws JsonMappingException { // first, general mappings while (true) { JavaType next = _mapAbstractType2(config, type); if (next == null) { return type; } // Should not have to worry about cycles; but better verify since they will invariably occur... :-) // (also: guard against invalid resolution to a non-related type) Class<?> prevCls = type.getRawClass(); Class<?> nextCls = next.getRawClass(); if ((prevCls == nextCls) || !prevCls.isAssignableFrom(nextCls)) { throw new IllegalArgumentException("Invalid abstract type resolution from "+type+" to "+next+": latter is not a subtype of former"); } type = next; } } /** * Method that will find abstract type mapping for specified type, doing a single * lookup through registered abstract type resolvers; will not do recursive lookups. */ private JavaType _mapAbstractType2(DeserializationConfig config, JavaType type) throws JsonMappingException { Class<?> currClass = type.getRawClass(); if (_factoryConfig.has

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>AbstractTypeResolvers()) { for (AbstractTypeResolver resolver : _factoryConfig.abstractTypeResolvers()) { JavaType concrete = resolver.findTypeMapping(config, type); if (concrete != null && concrete.getRawClass() != currClass) { return concrete; } } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl (partial): ValueInstantiators /********************************************************** */ /** * Value instantiator is created both based on creator annotations, * and on optional externally provided instantiators (registered through * module interface). */ @Override public ValueInstantiator findValueInstantiator(DeserializationContext ctxt, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); ValueInstantiator instantiator = null; // [JACKSON-633] Check @JsonValueInstantiator before anything else AnnotatedClass ac = beanDesc.getClassInfo(); Object instDef = ctxt.getAnnotationIntrospector().findValueInstantiator(ac); if (instDef != null) { instantiator = _valueInstantiatorInstance(config, ac, instDef); } if (instantiator == null) { /* Second: see if some of standard Jackson/JDK types might provide value * instantiators. */ instantiator = _findStdValueInstantiator(config, beanDesc); if (instantiator == null) { instantiator = _constructDefaultValueInstantiator(ctxt, beanDesc); } } // finally: anyone want to modify ValueInstantiator? if (_factoryConfig.hasValueInstantiators()) { for (ValueInstantiators insts : _factoryConfig.valueInstantiators()) { instantiator = insts.findValueInstantiator(config, beanDesc, instantiator); // let's do sanity check; easier to spot buggy handlers if (instantiator == null) { throw JsonMappingException.from(ctxt.getParser(), "Broken registered ValueInstantiators (of type "+insts.getClass().getName()+"): returned null ValueInstantiator"); } } } // Sanity check: does the chosen instantatior have incomplete creators? if (instantiator.getIncompleteParameter() != null) { final AnnotatedParameter nonAnnotatedParam = instantiator.getIncompleteParameter(); final AnnotatedWithParams ctor = nonAnnotatedParam.getOwner(); throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()+" of constructor "+ctor+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator"); } return instantiator; } private ValueInstantiator _findStdValueInstantiator(DeserializationConfig config, BeanDescription beanDesc) throws Json

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> a 'real' one result = new LinkedHashMap<AnnotatedWithParams,BeanPropertyDefinition[]>(); } defs = new BeanPropertyDefinition[owner.getParameterCount()]; result.put(owner, defs); } else { if (defs[index] != null) { throw new IllegalStateException("Conflict: parameter #"+index+" of "+owner +" bound to more than one property; "+defs[index]+" vs "+propDef); } } defs[index] = propDef; } } return result; } public ValueInstantiator _valueInstantiatorInstance(DeserializationConfig config, Annotated annotated, Object instDef) throws JsonMappingException { if (instDef == null) { return null; } ValueInstantiator inst; if (instDef instanceof ValueInstantiator) { return (ValueInstantiator) instDef; } if (!(instDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type " +instDef.getClass().getName() +"; expected type KeyDeserializer or Class<KeyDeserializer> instead"); } Class<?> instClass = (Class<?>)instDef; if (ClassUtil.isBogusClass(instClass)) { return null; } if (!ValueInstantiator.class.isAssignableFrom(instClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class "+instClass.getName() +"; expected Class<ValueInstantiator>"); } HandlerInstantiator hi = config.getHandlerInstantiator(); if (hi != null) { inst = hi.valueInstantiatorInstance(config, annotated, instClass); if (inst != null) { return inst; } } return (ValueInstantiator) ClassUtil.createInstance(instClass, config.canOverrideAccessModifiers()); } protected void _addDeserializerConstructors (DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker, AnnotationIntrospector intr, CreatorCollector creators, Map<AnnotatedWithParams,BeanPropertyDefinition[]> creatorParams) throws JsonMappingException { // First things first: the "default constructor" (zero-arg // constructor; whether implicit or explicit) is NOT included // in list of constructors, so needs to be handled separately. AnnotatedConstructor defaultCtor = beanDesc.findDefaultConstructor(); if (defaultCtor != null) { if (!creators.hasDefaultCreator() || intr.hasCreatorAnnotation(defaultCtor)) { creators.setDefaultCreator(defaultCtor); } } // may need to keep track for [#725] List<AnnotatedConstructor> implicitCtors = null; for (AnnotatedConstructor ctor : beanDesc.getConstructors

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> @Deprecated // in 2.6, remove from 2.7 protected boolean _hasExplicitParamName(AnnotatedParameter param, AnnotationIntrospector intr) { if (param != null && intr != null) { PropertyName n = intr.findNameForDeserialization(param); return (n != null) && n.hasSimpleName(); } return false; } /* /********************************************************** /* JsonDeserializerFactory impl: array deserializers /********************************************************** */ @Override public JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt, ArrayType type, final BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); JavaType elemType = type.getContentType(); // Very first thing: is deserializer hard-coded for elements? JsonDeserializer<Object> contentDeser = elemType.getValueHandler(); // Then optional type info: if type has been resolved, we may already know type deserializer: TypeDeserializer elemTypeDeser = elemType.getTypeHandler(); // but if not, may still be possible to find: if (elemTypeDeser == null) { elemTypeDeser = findTypeDeserializer(config, elemType); } // 23-Nov-2010, tatu: Custom array deserializer? JsonDeserializer<?> deser = _findCustomArrayDeserializer(type, config, beanDesc, elemTypeDeser, contentDeser); if (deser == null) { if (contentDeser == null) { Class<?> raw = elemType.getRawClass(); if (elemType.isPrimitive()) { return PrimitiveArrayDeserializers.forType(raw); } else if (raw == String.class) { return StringArrayDeserializer.instance; } } deser = new ObjectArrayDeserializer(type, contentDeser, elemTypeDeser); } // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyArrayDeserializer(config, type, beanDesc, deser); } } return deser; } /* /********************************************************** /* JsonDeserializerFactory impl: Collection(-like) deserializers /********************************************************** */ @Override public JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt, CollectionType type, BeanDescription beanDesc) throws JsonMappingException { JavaType contentType = type.getContentType(); // Very first thing: is deserializer hard-coded for elements? JsonDeserializer<Object> contentDeser = contentType.getValueHandler(); final

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> DeserializationConfig config = ctxt.getConfig(); // Then optional type info: if type has been resolved, we may already know type deserializer: TypeDeserializer contentTypeDeser = contentType.getTypeHandler(); // but if not, may still be possible to find: if (contentTypeDeser == null) { contentTypeDeser = findTypeDeserializer(config, contentType); } // 23-Nov-2010, tatu: Custom deserializer? JsonDeserializer<?> deser = _findCustomCollectionDeserializer(type, config, beanDesc, contentTypeDeser, contentDeser); if (deser == null) { Class<?> collectionClass = type.getRawClass(); if (contentDeser == null) { // not defined by annotation // One special type: EnumSet: if (EnumSet.class.isAssignableFrom(collectionClass)) { deser = new EnumSetDeserializer(contentType, null); } } } /* One twist: if we are being asked to instantiate an interface or * abstract Collection, we need to either find something that implements * the thing, or give up. * * Note that we do NOT try to guess based on secondary interfaces * here; that would probably not work correctly since casts would * fail later on (as the primary type is not the interface we'd * be implementing) */ if (deser == null) { if (type.isInterface() || type.isAbstract()) { CollectionType implType = _mapAbstractCollectionType(type, config); if (implType == null) { // [databind#292]: Actually, may be fine, but only if polymorphich deser enabled if (type.getTypeHandler() == null) { throw new IllegalArgumentException("Can not find a deserializer for non-concrete Collection type "+type); } deser = AbstractDeserializer.constructForNonPOJO(beanDesc); } else { type = implType; // But if so, also need to re-check creators... beanDesc = config.introspectForCreation(type); } } if (deser == null) { ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc); if (!inst.canCreateUsingDefault()) { // [databind#161]: No default constructor for ArrayBlockingQueue... if (type.getRawClass() == ArrayBlockingQueue.class) { return new ArrayBlockingQueueDeserializer(type, contentDeser, contentTypeDeser, inst); } } // Can use more optimal deserializer if content type is String, so: if (contentType.getRawClass() == String.class) { // no value type deserializer because Strings are one of natural/native types: deser

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> = new StringCollectionDeserializer(type, contentDeser, inst); } else { deser = new CollectionDeserializer(type, contentDeser, contentTypeDeser, inst); } } } // allow post-processing it too if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyCollectionDeserializer(config, type, beanDesc, deser); } } return deser; } protected CollectionType _mapAbstractCollectionType(JavaType type, DeserializationConfig config) { Class<?> collectionClass = type.getRawClass(); collectionClass = _collectionFallbacks.get(collectionClass.getName()); if (collectionClass == null) { return null; } return (CollectionType) config.constructSpecializedType(type, collectionClass); } // Copied almost verbatim from "createCollectionDeserializer" -- should try to share more code @Override public JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt, CollectionLikeType type, final BeanDescription beanDesc) throws JsonMappingException { JavaType contentType = type.getContentType(); // Very first thing: is deserializer hard-coded for elements? JsonDeserializer<Object> contentDeser = contentType.getValueHandler(); final DeserializationConfig config = ctxt.getConfig(); // Then optional type info (1.5): if type has been resolved, we may already know type deserializer: TypeDeserializer contentTypeDeser = contentType.getTypeHandler(); // but if not, may still be possible to find: if (contentTypeDeser == null) { contentTypeDeser = findTypeDeserializer(config, contentType); } JsonDeserializer<?> deser = _findCustomCollectionLikeDeserializer(type, config, beanDesc, contentTypeDeser, contentDeser); if (deser != null) { // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyCollectionLikeDeserializer(config, type, beanDesc, deser); } } } return deser; } /* /********************************************************** /* JsonDeserializerFactory impl: Map(-like) deserializers /********************************************************** */ @Override public JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt, MapType type, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); JavaType keyType = type.getKeyType(); JavaType contentType = type.getContentType(); // First: is there annotation-specified deserializer for values?

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> @SuppressWarnings("unchecked") JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler(); // Ok: need a key deserializer (null indicates 'default' here) KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler(); // Then optional type info (1.5); either attached to type, or resolved separately: TypeDeserializer contentTypeDeser = contentType.getTypeHandler(); // but if not, may still be possible to find: if (contentTypeDeser == null) { contentTypeDeser = findTypeDeserializer(config, contentType); } // 23-Nov-2010, tatu: Custom deserializer? JsonDeserializer<?> deser = _findCustomMapDeserializer(type, config, beanDesc, keyDes, contentTypeDeser, contentDeser); if (deser == null) { // Value handling is identical for all, but EnumMap requires special handling for keys Class<?> mapClass = type.getRawClass(); if (EnumMap.class.isAssignableFrom(mapClass)) { Class<?> kt = keyType.getRawClass(); if (kt == null || !kt.isEnum()) { throw new IllegalArgumentException("Can not construct EnumMap; generic (key) type not available"); } deser = new EnumMapDeserializer(type, null, contentDeser, contentTypeDeser); } // Otherwise, generic handler works ok. /* But there is one more twist: if we are being asked to instantiate * an interface or abstract Map, we need to either find something * that implements the thing, or give up. * * Note that we do NOT try to guess based on secondary interfaces * here; that would probably not work correctly since casts would * fail later on (as the primary type is not the interface we'd * be implementing) */ if (deser == null) { if (type.isInterface() || type.isAbstract()) { @SuppressWarnings("rawtypes") Class<? extends Map> fallback = _mapFallbacks.get(mapClass.getName()); if (fallback != null) { mapClass = fallback; type = (MapType) config.constructSpecializedType(type, mapClass); // But if so, also need to re-check creators... beanDesc = config.introspectForCreation(type); } else { // [Issue#292]: Actually, may be fine, but only if polymorphich deser enabled if (type.getTypeHandler() == null) { throw new IllegalArgumentException("Can not find a deserializer for non-concrete Map type "+type); } deser = AbstractDeserializer.constructForNonPOJO(beanDesc); } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> /********************************************************** /* JsonDeserializerFactory impl: other types /********************************************************** */ /** * Factory method for constructing serializers of {@link Enum} types. */ @Override public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); final Class<?> enumClass = type.getRawClass(); // 23-Nov-2010, tatu: Custom deserializer? JsonDeserializer<?> deser = _findCustomEnumDeserializer(enumClass, config, beanDesc); if (deser == null) { // May have @JsonCreator for static factory method: for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) { if (ctxt.getAnnotationIntrospector().hasCreatorAnnotation(factory)) { int argCount = factory.getParameterCount(); if (argCount == 1) { Class<?> returnType = factory.getRawReturnType(); // usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?) if (returnType.isAssignableFrom(enumClass)) { deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory); break; } } throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type " +enumClass.getName()+")"); } } // Need to consider @JsonValue if one found if (deser == null) { deser = new EnumDeserializer(constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod())); } } // and then post-process it too if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyEnumDeserializer(config, type, beanDesc, deser); } } return deser; } @Override public JsonDeserializer<?> createTreeDeserializer(DeserializationConfig config, JavaType nodeType, BeanDescription beanDesc) throws JsonMappingException { @SuppressWarnings("unchecked") Class<? extends JsonNode> nodeClass = (Class<? extends JsonNode>) nodeType.getRawClass(); // 23-Nov-2010, tatu: Custom deserializer? JsonDeserializer<?> custom = _findCustomTreeNodeDeserializer(nodeClass, config, beanDesc); if (custom != null) { return custom; } return JsonNodeDeserializer.getDeserializer(nodeClass); } @Override public JsonDeserializer<?> createReferenceDeserializer(DeserializationContext ctxt, ReferenceType type, BeanDescription beanDesc) throws JsonMappingException { JavaType contentType = type.getContentType(); // Very first thing

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>: is deserializer hard-coded for elements? JsonDeserializer<Object> contentDeser = contentType.getValueHandler(); final DeserializationConfig config = ctxt.getConfig(); // Then optional type info: if type has been resolved, we may already know type deserializer: TypeDeserializer contentTypeDeser = contentType.getTypeHandler(); if (contentTypeDeser == null) { // or if not, may be able to find: contentTypeDeser = findTypeDeserializer(config, contentType); } JsonDeserializer<?> deser = _findCustomReferenceDeserializer(type, config, beanDesc, contentTypeDeser, contentDeser); if (deser == null) { // Just one referential type as of JDK 1.7 / Java 7: AtomicReference (Java 8 adds Optional) if (AtomicReference.class.isAssignableFrom(type.getRawClass())) { // 19-Apr-2016, tatu: By default we'd get something that expect to see an // AtomicReference... but what we need is something else, so... return new AtomicReferenceDeserializer(contentType, contentTypeDeser, contentDeser); } } if (deser != null) { // and then post-process if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyReferenceDeserializer(config, type, beanDesc, deser); } } } return deser; } /* /********************************************************** /* JsonDeserializerFactory impl (partial): type deserializers /********************************************************** */ @Override public TypeDeserializer findTypeDeserializer(DeserializationConfig config, JavaType baseType) throws JsonMappingException { BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass()); AnnotatedClass ac = bean.getClassInfo(); AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType); /* Ok: if there is no explicit type info handler, we may want to * use a default. If so, config object knows what to use. */ Collection<NamedType> subtypes = null; if (b == null) { b = config.getDefaultTyper(baseType); if (b == null) { return null; } } else { subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(config, ac); } // May need to figure out default implementation, if none found yet // (note: check for abstract type is not 100% mandatory, more of an optimization) if ((b.getDefaultImpl() == null) && baseType

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>.isAbstract()) { JavaType defaultType = mapAbstractType(config, baseType); if (defaultType != null && defaultType.getRawClass() != baseType.getRawClass()) { b = b.defaultImpl(defaultType.getRawClass()); } } return b.buildTypeDeserializer(config, baseType, subtypes); } /** * Overridable method called after checking all other types. * * @since 2.2 */ protected JsonDeserializer<?> findOptionalStdDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { return OptionalHandlerFactory.instance.findDeserializer(type, ctxt.getConfig(), beanDesc); } /* /********************************************************** /* JsonDeserializerFactory impl (partial): key deserializers /********************************************************** */ @Override public KeyDeserializer createKeyDeserializer(DeserializationContext ctxt, JavaType type) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); KeyDeserializer deser = null; if (_factoryConfig.hasKeyDeserializers()) { BeanDescription beanDesc = config.introspectClassAnnotations(type.getRawClass()); for (KeyDeserializers d : _factoryConfig.keyDeserializers()) { deser = d.findKeyDeserializer(type, config, beanDesc); if (deser != null) { break; } } } // the only non-standard thing is this: if (deser == null) { if (type.isEnumType()) { return _createEnumKeyDeserializer(ctxt, type); } deser = StdKeyDeserializers.findStringBasedKeyDeserializer(config, type); } // and then new with 2.2: ability to post-process it too (Issue#120) if (deser != null) { if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyKeyDeserializer(config, type, deser); } } } return deser; } private KeyDeserializer _createEnumKeyDeserializer(DeserializationContext ctxt, JavaType type) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); Class<?> enumClass = type.getRawClass(); BeanDescription beanDesc = config.introspect(type); // 24-Sep-2015, bim: a key deserializer is the preferred thing. KeyDeserializer des = findKeyDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo()); if (des != null) { return des; } else { // 24-Sep-2015, bim

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>: if no key deser, look for enum deserializer first, then a plain deser. JsonDeserializer<?> custom = _findCustomEnumDeserializer(enumClass, config, beanDesc); if (custom != null) { return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, custom); } JsonDeserializer<?> valueDesForKey = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo()); if (valueDesForKey != null) { return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, valueDesForKey); } } EnumResolver enumRes = constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod()); // May have @JsonCreator for static factory method: final AnnotationIntrospector ai = config.getAnnotationIntrospector(); for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) { if (ai.hasCreatorAnnotation(factory)) { int argCount = factory.getParameterCount(); if (argCount == 1) { Class<?> returnType = factory.getRawReturnType(); // usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?) if (returnType.isAssignableFrom(enumClass)) { // note: mostly copied from 'EnumDeserializer.deserializerForCreator(...)' if (factory.getRawParameterType(0) != String.class) { throw new IllegalArgumentException("Parameter #0 type for factory method ("+factory+") not suitable, must be java.lang.String"); } if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(factory.getMember(), ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes, factory); } } throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type " +enumClass.getName()+")"); } } // [JACKSON-749] Also, need to consider @JsonValue, if one found return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes); } /* /********************************************************** /* Extended API /********************************************************** */ /** * Method called to create a type information deserializer for values of * given non-container property, if one is needed. * If not needed (no polymorphic handling configured for property), should return null. *<p> * Note that this method is only called for non-container bean properties, * and not for values in container types or root values (or container properties) * * @param baseType Declared base type of the value to deserializer (actual * deserializer type will be this type or its subtype)

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> * * @return Type deserializer to use for given base type, if one is needed; null if not. */ public TypeDeserializer findPropertyTypeDeserializer(DeserializationConfig config, JavaType baseType, AnnotatedMember annotated) throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, annotated, baseType); // Defaulting: if no annotations on member, check value class if (b == null) { return findTypeDeserializer(config, baseType); } // but if annotations found, may need to resolve subtypes: Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId( config, annotated, baseType); return b.buildTypeDeserializer(config, baseType, subtypes); } /** * Method called to find and create a type information deserializer for values of * given container (list, array, map) property, if one is needed. * If not needed (no polymorphic handling configured for property), should return null. *<p> * Note that this method is only called for container bean properties, * and not for values in container types or root values (or non-container properties) * * @param containerType Type of property; must be a container type * @param propertyEntity Field or method that contains container property */ public TypeDeserializer findPropertyContentTypeDeserializer(DeserializationConfig config, JavaType containerType, AnnotatedMember propertyEntity) throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType); JavaType contentType = containerType.getContentType(); // Defaulting: if no annotations on member, check class if (b == null) { return findTypeDeserializer(config, contentType); } // but if annotations found, may need to resolve subtypes: Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId( config, propertyEntity, contentType); return b.buildTypeDeserializer(config, contentType, subtypes); } /** * Helper method called to find one of default serializers for "well-known" * platform types: JDK-provided types, and small number of public Jackson * API types. * * @since 2.2 */ public JsonDeserializer<?> findDefaultDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { Class<?> rawType = type.getRawClass(); // Object ("untyped"), String equivalents: if (rawType ==

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import java.lang.reflect.Array; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.type.ArrayType; import com.fasterxml.jackson.databind.util.ObjectBuffer; /** * Basic serializer that can serialize non-primitive arrays. */ @JacksonStdImpl public class ObjectArrayDeserializer extends ContainerDeserializerBase<Object[]> implements ContextualDeserializer { private static final long serialVersionUID = 1L; // // Configuration /** * Full generic type of the array being deserialized */ protected final ArrayType _arrayType; /** * Flag that indicates whether the component type is Object or not. * Used for minor optimization when constructing result. */ protected final boolean _untyped; /** * Type of contained elements: needed for constructing actual * result array */ protected final Class<?> _elementClass; /** * Element deserializer */ protected JsonDeserializer<Object> _elementDeserializer; /** * If element instances have polymorphic type information, this * is the type deserializer that can handle it */ protected final TypeDeserializer _elementTypeDeserializer; /** * Specific override for this instance (from proper, or global per-type overrides) * to indicate whether single value may be taken to mean an unwrapped one-element array * or not. If null, left to global defaults. * * @since 2.7 */ protected final Boolean _unwrapSingle; /* /********************************************************** /* Life-cycle /********************************************************** */ public ObjectArrayDeserializer(ArrayType arrayType, JsonDeserializer<Object> elemDeser, TypeDeserializer elemTypeDeser) { super(arrayType); _arrayType = arrayType; _elementClass = arrayType.getContentType().getRawClass(); _untyped = (_elementClass == Object.class); _elementDeserializer = elemDeser; _elementTypeDeserializer = elemTypeDeser; _unwrapSingle = null; } protected ObjectArrayDeserializer(ObjectArrayDeserializer base, JsonDeserializer<Object> elemDeser, TypeDeserializer elemTypeDeser, Boolean unwrapSingle) { super(base._arrayType); _arrayType = base._arrayType; _elementClass = base._elementClass; _

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>untyped = base._untyped; _elementDeserializer = elemDeser; _elementTypeDeserializer = elemTypeDeser; _unwrapSingle = unwrapSingle; } /** * Overridable fluent-factory method used to create contextual instances */ public ObjectArrayDeserializer withDeserializer(TypeDeserializer elemTypeDeser, JsonDeserializer<?> elemDeser) { return withResolved(elemTypeDeser, elemDeser, _unwrapSingle); } /** * @since 2.7 */ @SuppressWarnings("unchecked") public ObjectArrayDeserializer withResolved(TypeDeserializer elemTypeDeser, JsonDeserializer<?> elemDeser, Boolean unwrapSingle) { if ((unwrapSingle == _unwrapSingle) && (elemDeser == _elementDeserializer) && (elemTypeDeser == _elementTypeDeserializer)) { return this; } return new ObjectArrayDeserializer(this, (JsonDeserializer<Object>) elemDeser, elemTypeDeser, unwrapSingle); } @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { JsonDeserializer<?> deser = _elementDeserializer; Boolean unwrapSingle = findFormatFeature(ctxt, property, _arrayType.getRawClass(), JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY); // May have a content converter deser = findConvertingContentDeserializer(ctxt, property, deser); final JavaType vt = _arrayType.getContentType(); if (deser == null) { deser = ctxt.findContextualValueDeserializer(vt, property); } else { // if directly assigned, probably not yet contextual, so: deser = ctxt.handleSecondaryContextualization(deser, property, vt); } TypeDeserializer elemTypeDeser = _elementTypeDeserializer; if (elemTypeDeser != null) { elemTypeDeser = elemTypeDeser.forProperty(property); } return withResolved(elemTypeDeser, deser, unwrapSingle); } @Override // since 2.5 public boolean isCachable() { // Important: do NOT cache if polymorphic values, or ones with custom deserializer return (_elementDeserializer == null) && (_elementTypeDeserializer == null); } /* /********************************************************** /* ContainerDeserializerBase API /********************************************************** */ @Override public JavaType getContentType() { return _arrayType.getContentType(); } @Override public JsonDeserializer<Object> getContentDeserializer() { return _elementDeserializer; } /* /********************************************************** /* JsonDeserializer API /********************************************************** */ @Override public Object[] deserialize(JsonParser p, DeserializationContext ctxt) throws

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) { String str = p.getText(); if (str.length() == 0) { return null; } } // Can we do implicit coercion to a single-element array still? boolean canWrap = (_unwrapSingle == Boolean.TRUE) || ((_unwrapSingle == null) && ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)); if (!canWrap) { // One exception; byte arrays are generally serialized as base64, so that should be handled if (p.getCurrentToken() == JsonToken.VALUE_STRING // note: not `byte[]`, but `Byte[]` -- former is primitive array && _elementClass == Byte.class) { return deserializeFromBase64(p, ctxt); } throw ctxt.mappingException(_arrayType.getRawClass()); } JsonToken t = p.getCurrentToken(); Object value; if (t == JsonToken.VALUE_NULL) { value = _elementDeserializer.getNullValue(ctxt); } else if (_elementTypeDeserializer == null) { value = _elementDeserializer.deserialize(p, ctxt); } else { value = _elementDeserializer.deserializeWithType(p, ctxt, _elementTypeDeserializer); } // Ok: bit tricky, since we may want T[], not just Object[] Object[] result; if (_untyped) { result = new Object[1]; } else { result = (Object[]) Array.newInstance(_elementClass, 1); } result[0] = value; return result; } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>) || value.isEmpty(); } @Override public boolean hasSingleElement(Collection<?> value) { Iterator<?> it = value.iterator(); if (!it.hasNext()) { return false; } it.next(); return !it.hasNext(); } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public final void serialize(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException { final int len = value.size(); if (len == 1) { if (((_unwrapSingle == null) && provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)) || (_unwrapSingle == Boolean.TRUE)) { serializeContents(value, jgen, provider); return; } } jgen.writeStartArray(len); serializeContents(value, jgen, provider); jgen.writeEndArray(); } @Override public void serializeContents(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException { if (_elementSerializer != null) { serializeContentsUsing(value, jgen, provider, _elementSerializer); return; } Iterator<?> it = value.iterator(); if (!it.hasNext()) { return; } PropertySerializerMap serializers = _dynamicSerializers; final TypeSerializer typeSer = _valueTypeSerializer; int i = 0; try { do { Object elem = it.next(); if (elem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicSerializers; } if (typeSer == null) { serializer.serialize(elem, jgen, provider); } else { serializer.serializeWithType(elem, jgen, provider, typeSer); } } ++i; } while (it.hasNext()); } catch (Exception e) { wrapAndThrow(provider, e, value, i); } } public void serializeContentsUsing(Collection<?> value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException, JsonGenerationException { Iterator<?> it = value.iterator(); if (it.hasNext()) { TypeSerializer typeSer = _valueTypeSerializer; int

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>WithErrorWrapping(p, ctxt, creatorProp))) { p.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); bean = null; // never gets here } if (bean == null) { throw ctxt.instantiationException(_beanType.getRawClass(), "JSON Creator returned null"); } // [databind#631]: Assign current value, to be accessible by custom serializers p.setCurrentValue(bean); // polymorphic? if (bean.getClass() != _beanType.getRawClass()) { return handlePolymorphic(p, ctxt, bean, unknown); } if (unknown != null) { // nope, just extra unknown stuff... bean = handleUnknownProperties(ctxt, bean, unknown); } // or just clean? return deserialize(p, ctxt, bean); } continue; } // Object Id property? if (buffer.readIdProperty(propName)) { continue; } // regular property? needs buffering SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { buffer.bufferProperty(prop, _deserializeWithErrorWrapping(p, ctxt, prop)); continue; } // As per [JACKSON-313], things marked as ignorable should not be // passed to any setter if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(p, ctxt, handledType(), propName); continue; } // "any property"? if (_anySetter != null) { try { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt)); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); } continue; } // Ok then, let's collect the whole field; name and value if (unknown == null) { unknown = new TokenBuffer(p, ctxt); } unknown.writeFieldName(propName); unknown.copyCurrentStructure(p); } // We hit END_OBJECT, so: Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); bean = null; // never gets here } if (unknown != null) { // polymorphic? if (bean.getClass() != _beanType.getRawClass()) { return handlePolymorphic(null

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>, ctxt, bean, unknown); } // no, just some extra unknown properties return handleUnknownProperties(ctxt, bean, unknown); } return bean; } protected final Object _deserializeWithErrorWrapping(JsonParser p, DeserializationContext ctxt, SettableBeanProperty prop) throws IOException { try { return prop.deserialize(p, ctxt); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), prop.getName(), ctxt); // never gets here, unless caller declines to throw an exception return null; } } /** * Helper method called for rare case of pointing to {@link JsonToken#VALUE_NULL} * token. While this is most often an erroneous condition, there is one specific * case with XML handling where polymorphic type with no properties is exposed * as such, and should be handled same as empty Object. * * @since 2.7 */ protected Object deserializeFromNull(JsonParser p, DeserializationContext ctxt) throws IOException { // 17-Dec-2015, tatu: Highly specialized case, mainly to support polymorphic // "empty" POJOs deserialized from XML, where empty XML tag synthesizes a // `VALUE_NULL` token. if (p.requiresCustomCodec()) { // not only XML module, but mostly it... @SuppressWarnings("resource") TokenBuffer tb = new TokenBuffer(p, ctxt); tb.writeEndObject(); JsonParser p2 = tb.asParser(p); p2.nextToken(); // to point to END_OBJECT // note: don't have ObjectId to consider at this point, so: Object ob = _vanillaProcessing ? vanillaDeserialize(p2, ctxt, JsonToken.END_OBJECT) : deserializeFromObject(p2, ctxt); p2.close(); return ob; } throw ctxt.mappingException(handledType()); } /* /********************************************************** /* Deserializing when we have to consider an active View /********************************************************** */ protected final Object deserializeWithView(JsonParser p, DeserializationContext ctxt, Object bean, Class<?> activeView) throws IOException { if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) { String propName = p.getCurrentName(); do { p.nextToken(); // TODO: 06-Jan-2015, tatu: try streamlining call sequences here as well SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { if (!prop.visibleInView(activeView)) { p.

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> SettableBeanProperty creatorProp = creator.findCreatorProperty(propName); if (creatorProp != null) { // Last creator property to set? if (buffer.assignParameter(creatorProp, _deserializeWithErrorWrapping(p, ctxt, creatorProp))) { t = p.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); continue; // never gets here } // [databind#631]: Assign current value, to be accessible by custom serializers p.setCurrentValue(bean); // if so, need to copy all remaining tokens into buffer while (t == JsonToken.FIELD_NAME) { p.nextToken(); // to skip name tokens.copyCurrentStructure(p); t = p.nextToken(); } tokens.writeEndObject(); if (bean.getClass() != _beanType.getRawClass()) { // !!! 08-Jul-2011, tatu: Could probably support; but for now // it's too complicated, so bail out tokens.close(); throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values"); } return _unwrappedPropertyHandler.processUnwrapped(p, ctxt, bean, tokens); } continue; } // Object Id property? if (buffer.readIdProperty(propName)) { continue; } // regular property? needs buffering SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { buffer.bufferProperty(prop, _deserializeWithErrorWrapping(p, ctxt, prop)); continue; } // Things marked as ignorable should not be passed to any setter if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(p, ctxt, handledType(), propName); continue; } tokens.writeFieldName(propName); tokens.copyCurrentStructure(p); // "any property"? if (_anySetter != null) { try { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt)); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); } } } // We hit END_OBJECT, so: Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); return null; // never gets here } return _unwrapped

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>) { try { _anySetter.deserializeAndSet(p, ctxt, bean, propName); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } // Unknown: let's call handler method handleUnknownProperty(p, ctxt, bean, propName); } // and when we get this far, let's try finalizing the deal: return ext.complete(p, ctxt, bean); } @SuppressWarnings("resource") protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p, DeserializationContext ctxt) throws IOException { final ExternalTypeHandler ext = _externalTypeIdHandler.start(); final PropertyBasedCreator creator = _propertyBasedCreator; PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader); TokenBuffer tokens = new TokenBuffer(p, ctxt); tokens.writeStartObject(); JsonToken t = p.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) { String propName = p.getCurrentName(); p.nextToken(); // to point to value // creator property? SettableBeanProperty creatorProp = creator.findCreatorProperty(propName); if (creatorProp != null) { // first: let's check to see if this might be part of value with external type id: // 11-Sep-2015, tatu: Important; do NOT pass buffer as last arg, but null, // since it is not the bean if (ext.handlePropertyValue(p, ctxt, propName, null)) { ; } else { // Last creator property to set? if (buffer.assignParameter(creatorProp, _deserializeWithErrorWrapping(p, ctxt, creatorProp))) { t = p.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); continue; // never gets here } // if so, need to copy all remaining tokens into buffer while (t == JsonToken.FIELD_NAME) { p.nextToken(); // to skip name tokens.copyCurrentStructure(p); t = p.nextToken(); } if (bean.getClass() != _beanType.getRawClass()) { // !!! 08-Jul-2011, tatu: Could theoretically support; but for now // it's too complicated, so bail out throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values"); }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>package com.fasterxml.jackson.databind.util; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.AnnotatedClass; import com.fasterxml.jackson.databind.type.ClassKey; /** * Helper class for caching resolved root names. */ public class RootNameLookup implements java.io.Serializable { private static final long serialVersionUID = 1L; /** * For efficient operation, let's try to minimize number of times we * need to introspect root element name to use. */ protected transient LRUMap<ClassKey,PropertyName> _rootNames; public RootNameLookup() { _rootNames = new LRUMap<ClassKey,PropertyName>(20, 200); } public PropertyName findRootName(JavaType rootType, MapperConfig<?> config) { return findRootName(rootType.getRawClass(), config); } public PropertyName findRootName(Class<?> rootType, MapperConfig<?> config) { ClassKey key = new ClassKey(rootType); PropertyName name = _rootNames.get(key); if (name != null) { return name; } BeanDescription beanDesc = config.introspectClassAnnotations(rootType); AnnotationIntrospector intr = config.getAnnotationIntrospector(); AnnotatedClass ac = beanDesc.getClassInfo(); name = intr.findRootName(ac); // No answer so far? Let's just default to using simple class name if (name == null || !name.hasSimpleName()) { // Should we strip out enclosing class tho? For now, nope: name = PropertyName.construct(rootType.getSimpleName()); } _rootNames.put(key, name); return name; } /* /********************************************************** /* Serializable overrides /********************************************************** */ /** * Need to override to reproduce cache object via constructor, instead * of serialize/deserialize (since we do NOT want to retain cached data) */ protected Object readResolve() { return new RootNameLookup(); } }

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> factory at this point... */ // 05-Sep-2013, tatu: I _think_ this can be considered a primary property... ser = provider.findPrimaryPropertySerializer(t, property); /* 09-Dec-2010, tatu: Turns out we must add special handling for * cases where "native" (aka "natural") type is being serialized, * using standard serializer */ boolean forceTypeInformation = isNaturalTypeWithStdHandling(t.getRawClass(), ser); return withResolved(property, ser, forceTypeInformation); } } else { // 05-Sep-2013, tatu: I _think_ this can be considered a primary property... ser = provider.handlePrimaryContextualization(ser, property); return withResolved(property, ser, _forceTypeInformation); } return this; } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public void serialize(Object bean, JsonGenerator jgen, SerializerProvider prov) throws IOException { try { Object value = _accessorMethod.invoke(bean); if (value == null) { prov.defaultSerializeNull(jgen); return; } JsonSerializer<Object> ser = _valueSerializer; if (ser == null) { Class<?> c = value.getClass(); /* 10-Mar-2010, tatu: Ideally we would actually separate out type * serializer from value serializer; but, alas, there's no access * to serializer factory at this point... */ // let's cache it, may be needed soon again ser = prov.findTypedValueSerializer(c, true, _property); } ser.serialize(value, jgen, prov); } catch (IOException ioe) { throw ioe; } catch (Exception e) { Throwable t = e; // Need to unwrap this specific type, to see infinite recursion... while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors shouldn't be wrapped (and often can't, as well) if (t instanceof Error) { throw (Error) t; } // let's try to indicate the path best we can... throw JsonMappingException.wrapWithPath(t, bean, _accessorMethod.getName() + "()"); } } @Override public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer0) throws IOException { // Regardless of other parts, first need to find value to serialize:

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>, tatu: First things first; for JSON Schema introspection, * Enums are special, and unfortunately we will need to add special * handling here (see https://github.com/FasterXML/jackson-module-jsonSchema/issues/57 * for details). */ Class<?> decl = (typeHint == null) ? null : typeHint.getRawClass(); if (decl == null) { decl = _accessorMethod.getDeclaringClass(); } if ((decl != null) && (decl.isEnum())) { if (_acceptJsonFormatVisitorForEnum(visitor, typeHint, decl)) { return; } } JsonSerializer<Object> ser = _valueSerializer; if (ser == null) { if (typeHint == null) { if (_property != null) { typeHint = _property.getType(); } if (typeHint == null) { typeHint = visitor.getProvider().constructType(_handledType); } } ser = visitor.getProvider().findTypedValueSerializer(typeHint, false, _property); if (ser == null) { visitor.expectAnyFormat(typeHint); return; } } ser.acceptJsonFormatVisitor(visitor, null); } /** * Overridable helper method used for special case handling of schema information for * Enums * * @return True if method handled callbacks; false if not; in latter case caller will * send default callbacks * * @since 2.6 */ protected boolean _acceptJsonFormatVisitorForEnum(JsonFormatVisitorWrapper visitor, JavaType typeHint, Class<?> enumType) throws JsonMappingException { // Copied from EnumSerializer#acceptJsonFormatVisitor JsonStringFormatVisitor stringVisitor = visitor.expectStringFormat(typeHint); if (stringVisitor != null) { Set<String> enums = new LinkedHashSet<String>(); for (Object en : enumType.getEnumConstants()) { try { enums.add(String.valueOf(_accessorMethod.invoke(en))); } catch (Exception e) { Throwable t = e; while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) { throw (Error) t; } throw JsonMappingException.wrapWithPath(t, en, _accessorMethod.getName() + "()"); } } stringVisitor.enumTypes(enums); } return true; } protected boolean isNaturalTypeWithStdHandling(Class<?> rawType, JsonSerializer<?> ser) { // First: do we have a natural type being handled?

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS>.getHandlerInstantiator(); } /* /********************************************************** /* Configuration: type and subtype handling /********************************************************** */ /** * Method called to locate a type info handler for types that do not have * one explicitly declared via annotations (or other configuration). * If such default handler is configured, it is returned; otherwise * null is returned. */ public final TypeResolverBuilder<?> getDefaultTyper(JavaType baseType) { return _base.getTypeResolverBuilder(); } public abstract SubtypeResolver getSubtypeResolver(); public final TypeFactory getTypeFactory() { return _base.getTypeFactory(); } /** * Helper method that will construct {@link JavaType} for given * raw class. * This is a simple short-cut for: *<pre> * getTypeFactory().constructType(cls); *</pre> */ public final JavaType constructType(Class<?> cls) { return getTypeFactory().constructType(cls); } /** * Helper method that will construct {@link JavaType} for given * type reference * This is a simple short-cut for: *<pre> * getTypeFactory().constructType(valueTypeRef); *</pre> */ public final JavaType constructType(TypeReference<?> valueTypeRef) { return getTypeFactory().constructType(valueTypeRef.getType()); } public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) { return getTypeFactory().constructSpecializedType(baseType, subclass); } /* /********************************************************** /* Configuration: introspection support /********************************************************** */ /** * Accessor for getting bean description that only contains class * annotations: useful if no getter/setter/creator information is needed. */ public BeanDescription introspectClassAnnotations(Class<?> cls) { return introspectClassAnnotations(constructType(cls)); } /** * Accessor for getting bean description that only contains class * annotations: useful if no getter/setter/creator information is needed. */ public abstract BeanDescription introspectClassAnnotations(JavaType type); /** * Accessor for getting bean description that only contains immediate class * annotations: ones from the class, and its direct mix-in, if any, but * not from super types. */ public BeanDescription introspectDirectClassAnnotations(Class<?> cls) { return introspectDirectClassAnnotations(constructType(cls)); } /** * Accessor for getting bean description that only contains immediate class * annotations: ones from the class, and its direct mix-in, if any, but * not from super types. */ public abstract BeanDescription introspectDirectClassAnnotations(JavaType type); /*

JacksonDatabind, 47

<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB> public JavaType refineSerializationType(final MapperConfig<?> config, final Annotated a, final JavaType baseType) throws JsonMappingException { JavaType type = baseType; final TypeFactory tf = config.getTypeFactory(); // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // now-deprecated secondary methods; this because while // direct sub-class not yet retrofitted may only override // those methods. With 2.8 or later we may consider removal // of these methods // Ok: start by refining the main type itself; common to all types Class<?> serClass = findSerializationType(a); if (serClass != null) { if (type.hasRawClass(serClass)) { // 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of // static typing this way type = type.withStaticTyping(); } else { <CHANGES> <CHANGEE> try { // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // may be needed here too in future? <CHANGES> <CHANGEE> type = tf.constructGeneralizedType(type, serClass); <CHANGES> <CHANGEE> } catch (IllegalArgumentException iae) { throw new JsonMappingException(null, String.format("Failed to widen type %s with annotation (value %s), from '%s': %s", type, serClass.getName(), a.getName(), iae.getMessage()), iae); } } } // Then further processing for container types // First, key type (for Maps, Map-like types): if (type.isMapLikeType()) { JavaType keyType = type.getKeyType(); <FILEE> <SCANS> 2.4 and before, was final), // at least if they can provide access to actual size of value and use `writeStartArray()` // variant that passes size of array to output, which is helpful with some data formats @Override public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException { if (provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED) && hasSingleElement(value)) { serializeContents(value, gen, provider); return; } gen.writeStartArray(); // [databind#631]: Assign current value, to be accessible by custom serializers gen.setCurrentValue(value); serializeContents(value, gen, provider); gen.writeEndArray(); } @Override public void serializeWithType(T value, JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer) throws IOException { // note: let's NOT consider [JACKSON-805] here; gets too complicated, and probably just won't work typeSer.writeTypePrefixForArray(value, gen); // [databind#631]: Assign current value, to be accessible by custom serializers gen.setCurrentValue(value); serializeContents(value, gen, provider); typeSer.writeTypeSuffixForArray(value, gen); } protected abstract void serializeContents(T value, JsonGenerator gen, SerializerProvider provider) throws IOException; @SuppressWarnings("deprecation") @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { ObjectNode o = createSchemaNode("array", true); JavaType contentType = _elementType; if (contentType != null) { JsonNode schemaNode = null; // 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped? if (contentType.getRawClass() != Object.class) { JsonSerializer<Object> ser = provider.findValueSerializer(contentType, _property); if (ser instanceof SchemaAware) { schemaNode = ((SchemaAware) ser).getSchema(provider, null); } } if (schemaNode == null) { schemaNode = com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode(); } o.set("items", schemaNode); } return o; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonSerializer<?> valueSer = _elementSerializer; if (valueSer == null) { valueSer = visitor.getProvider().findValueSerializer(_elementType, _property